6

many2many 関係に余分なフィールドがある通常の状況にあるとします。

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

# other models which are unrelated to the ones above..

class Trip(models.Model):
  placeVisited  = models.ForeignKey(Place)
  visitor  = models.ForeignKey(Person)
 pleasuretrip = models.Boolean()

class Place(models.Model):
  name = models.CharField(max_length=128)

Inline を介して表示されるメンバーシップ フォームにいくつかのフィールドを追加したいと考えています。これらのフィールドは基本的に、別のモデル (Trip) のインスタンス化へのショートカットです。旅行は独自の管理ビューを持つことができますが、これらのショートカットが必要なのは、私のプロジェクト パートナーがシステムに「メンバーシップ」データを入力しているときに、たまたま「旅行」情報も手元にあるためです (また、メンバーシップの情報の一部は、 Trip etc. などにコピーされます)。

したがって、Membership Inline に 2 つの追加フィールド (placeVisited とpleasuretrip) があれば、Person インスタンスと一緒にバックグラウンドで Trip モデルをインスタンス化できます...

独自のフォームを定義することで、インライン ビューにフィールドを簡単に追加できることがわかりました。しかし、データが入力されたら、必要な保存操作を実行するためにいつ、どのようにそれらを参照すればよいでしょうか?

class MyForm(forms.ModelForm):
 place = forms.ModelChoiceField(required=False, queryset=Place.objects.all(), label="place",)
 pleasuretrip = forms.BooleanField(required=False, label="...")

class MembershipInline(admin.TabularInline):
 model = Membership
 form = MyForm
    def save_model(self, request, obj, form, change):
        place = form.place
        pleasuretrip = form.pleasuretrip
        person = form.person
        ....
        # now I can create Trip instances with those data
        ....
        obj.save()

class GroupAdmin(admin.ModelAdmin):
 model = Group
 ....
 inlines = (MembershipInline,)

これは機能していないようです... save_formsetメソッドにも少し困惑しています...おそらくそれを使用する必要がありますか?助けてくれてありがとう!!!!

4

2 に答える 2

14

syn が彼の回答で指摘しているように、TabularInline と StackedInline の場合、インラインを含む ModelAdmin 内の save_formset メソッドをオーバーライドする必要があります。

GroupAdmin(admin.ModelAdmin):
    model = Group
    ....
    inlines = (MembershipInline,)

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)

        for instance in instances:
            if isinstance(instance, Member): #Check if it is the correct type of inline
                if(not instance.author):
                    instance.author = request.user
                else:
                    instance.modified_by = request.user            
                instance.save()
于 2010-08-25T18:24:40.010 に答える
2

私はちょうどこの同じ問題にぶつかりました.save_formsetとsave_modelの両方がインラインで呼び出されないことが解決策のようです. 代わりに、親である呼び出されているフォームセットに実装する必要があります。

model = Group
    ....
    inlines = (MembershipInline,)

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)

        for instance in instances:
            # Here an instance is a MembershipInline formset NOT a group...
            instance.someunsetfield = something

            # I think you are creating new objects, so you could do it here.
            instance.save()
于 2010-03-25T10:23:15.453 に答える