24

その質問はこれに似ているかもしれませんが、そうではありません...

私は次のようなモデル構造を持っています:

class Customer(models.Model):
    ....

class CustomerCompany(models.Model):
    customer = models.ForeignKey(Customer)
    type = models.SmallIntegerField(....)

私はを使用しInlineModelsており、2つのタイプがありCustomerCompany.typeます。CustomerCompanyだから私はとオーバーライドのために2つの異なるインラインを定義しますInlineModelAdmin.queryset

class CustomerAdmin(admin.ModelAdmin):
    inlines=[CustomerCompanyType1Inline, CustomerCompanyType2Inline]


class CustomerCompanyType1Inline(admin.TabularInline):
    model = CustomerCompany
    def queryset(self, request):
        return super(CustomerCompanyType1Inline, self).queryset(request).filter(type=1)

class CustomerCompanyType2Inline(admin.TabularInline):
    model = CustomerCompany
    def queryset(self, request):
        return super(CustomerCompanyType2Inline, self).queryset(request).filter(type=2)
    

ここまではすべて素晴らしくて良いですが、の新しいレコードを追加するには、の ようなメソッドをオーバーライドできないため、のフィールドInlineModelAdminを表示する必要があります。typeCustomerCompanyAdminFormsaveInlineModelAdmin

class CustomerCompanyType2Inline(admin.TabularInline):
    model = CustomerCompany
    def queryset(self, request):
        return super(CustomerCompanyType2Inline, self).queryset(request).filter(type=2)
    #Following override do not work
    def save_model(self, request, obj, form, change):
        obj.type=2
        obj.save()

sender私の信号は同じになるので、信号を使用することも解決策ではありません。そのため、どの信号を送信し、何Modelを送信する必要があるかを検出できません...InlineModelAdmintype

type保存する前にフィールドを設定する方法はありますか?

4

4 に答える 4

39

Alasdair の答えは間違っていませんが、問題を引き起こす可能性のある問題点がいくつかあります。最初に、変数名として使用してフォームセットをループすることによりform、メソッド for に渡された値を実際にオーバーライドしますform。大したことではありませんが、フォームセットから直接コミットせずに保存できるので、その方法をお勧めします。第二に、すべての重要なformset.save_m2m()ことが答えから除外されました。実際のDjango ドキュメントでは、次のことを推奨しています。

def save_formset(self, request, form, formset, change):
    instances = formset.save(commit=False)
    for instance in instances:
        # Do something with `instance`
        instance.save()
    formset.save_m2m()

あなたが遭遇しようとしている問題は、save_formsetメソッドがインラインではなく親に行かなければならずModelAdmin、そこから、どのインラインが実際に利用されているかを知る方法がないということです. 2 つの「タイプ」を持つ obj があり、すべてのフィールドが同じである場合は、プロキシ モデルを使用する必要があり、それぞれの保存メソッドを実際にオーバーライドして、適切なタイプを自動的に設定できます。

class CustomerCompanyType1(CustomerCompany):
    class Meta:
       proxy = True

    def save(self, *args, **kwargs):
        self.type = 1
        super(CustomerCompanyType1, self).save(*args, **kwargs)

class CustomerCompanyType2(CustomerCompany):
    class Meta:
       proxy = True

    def save(self, *args, **kwargs):
        self.type = 2
        super(CustomerCompanyType2, self).save(*args, **kwargs)

次に、インラインで特別なことをする必要はまったくありません。適切なプロキシ モデルを使用するように既存のインライン管理クラスを変更するだけで、すべてが自動的に解決されます。

于 2011-11-28T15:58:09.267 に答える
5

save_formsetオーバーライドできるメソッドがあります。どのインラインがformsetどういうわけか表現する必要があります。

def save_formset(self, request, form, formset, change):
    instances = formset.save(commit=False)
    for instance in instances:
        # Do something with `instance`
        instance.save()
    formset.save_m2m()
于 2011-11-28T15:12:33.227 に答える