1

次のモデルがあるとします-

class Item(models.Model):
    name = models.CharField(max_length=150)
    value = models.DecimalField(max_digits=12,decimal_places=2)

class Organization(models.Model):
    name = models.CharField(max_length=150)
    items = models.ManyToManyField(Item, through='Customizable')

class Customizable(models.Model):
    organization = models.ForeignKey(Organization)
    item = models.ForeignKey (Item)
    value = models.DecimalField(max_digits=12,decimal_places=2)

多くの場合、 にitems「割り当て」られると、関連するオブジェクトorganizationに最初に記録された値と同じ値になります。Itemただし、場合によっては、組織に割り当てられたアイテムが上書きされることがありますvalue(したがって、中間モデル)。元の値を上書きすることはめったに起こらないので (実際には起こります)、ユーザーがインスタンスitemsのリストから必要なものを選択Itemして、それらを組織のインスタンスに割り当てることができるようにしたいと考えています。ユーザーは、一括割り当てが完了した後で個々の値を上書きするオプションを利用できます。

だから私は次の単純なModelFormを持っています -

class AssignItemsForm(forms.ModelForm):
    items = forms.ModelMultipleChoiceField(queryset=Item.objects.all(),required=False,widget=forms.CheckboxSelectMultiple)
    class Meta:
        model = Organization
        exclude = ('name',)

モデルがあるthroughので、単純な form.save() は機能しません。(i)Customizableユーザーが選択したアイテムに対応するインスタンスを保存し、(ii) 永続化されたインスタンスが、foreignkey によって関連付けられたインスタンスから取得された対応するインスタンスからCustomizable適切に取得されていることを確認する必要があります。valuevalueitem

私はビューでそれを処理しようとしています (しかし、私の心はブロックされています) -

def assign_items(request, oid):
    organization = Organization.objects.get(id=oid)
    if request.method == 'POST':
        form = AssignItemsForm(data=request.POST, instance=organization)
        if form.is_valid():
            current_organization = form.save(commit=False)
            #
            #placeholder to save Customizable instances here
            #
            return HttpResponseRedirect(reverse('redirect-someplace-else'))
    else:
        form = AssignItemsForm(instance=organization,)
    return render_to_response("assign_items.html", {"form": form,}, context_instance=RequestContext(request))
4

3 に答える 3

1

メソッドを使用する必要がありますsave_m2m

def assign_items(request, oid):
    organization = Organization.objects.get(id=oid)
    if request.method == 'POST':
        form = AssignItemsForm(data=request.POST, instance=organization)
        if form.is_valid():
            current_organization = form.save(commit=False)

            current_organization.save()

            form.save_m2m()

            return HttpResponseRedirect(reverse('redirect-someplace-else'))
    else:
        form = AssignItemsForm(instance=organization,)
    return render_to_response("assign_items.html", {"form": form,}, context_instance=RequestContext(request))

詳細については、ここを参照してください。

http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method

于 2010-10-05T10:24:54.130 に答える
0

saveModelFormのメソッドをオーバーライドします。こうすることで、複数の場所でフォームを使用する必要がある場合でも、同じことを繰り返す必要がなくなります。

詳細については、この回答を参照してください。

https://stackoverflow.com/a/40822731/2863603

于 2016-11-26T20:30:58.873 に答える
0

私はこれに別の方法でアプローチします。m2m の中間モデルがあります。AssignItemsFormしたがって、この中間モデルに裏打ちされるべきだと私は主張します。したがって、次のように変更します。

# forms.py
class AssignItemsForm(forms.ModelForm):
    value = forms.DecimalField(max_digits=12, decimal_places=2, required = False)

    class Meta:
        model = Customizable

次に、ユーザーが別の値を選択できるようにする問題です。これを行うためにvalue、モデルのフィールドをオプション ( required = False) にしました。次に、ユーザーが明示的な値を指定したかどうかを確認します。Itemそうでない場合は、のデフォルト値が使用されると想定しています。このためcleanに、フォームのメソッドをオーバーライドしています:

    def clean(self):
        super(AssignItemsForm, self).clean()
        value, item = self.cleaned_data.get('value'), self.cleaned_data.get('item')
        if not value:
            value = item.value
        self.cleaned_data['value'] = value
        return self.cleaned_data

そして最後に、これを管理者でテストしました。

# admin.py
from app.forms import AssignItemsForm

class CAdmin(admin.ModelAdmin):
    form = AssignItemsForm

admin.site.register(Item)
admin.site.register(Organization)
admin.site.register(Customizable, CAdmin)

このようにして引き続き使用できるためform.save()、ビューでのカスタム操作を回避できます。アイテムを割り当てるために組織が自動的に選択されるようにするには、ビューを少し変更する必要があります。

# views.py
def assign_items(request, oid):
    organization = Organization.objects.get(id=oid)
    if request.method == 'POST':
        form = AssignItemsForm(data=request.POST.copy())
        form.save()
    else:
        form = AssignItemsForm(initial = {'organization': organization})
    ...
于 2010-10-05T10:16:34.633 に答える