Django管理者のインラインで、同じタイプのモデルフィールドのフォームフィールドを入力するために異なるウィジェットを提供したいと思います。Django adminインラインをオーバーライドして各インスタンスのformfield_for_dbfieldを指定する最も簡単な方法
私は店のアプリケーションでEntity-Attribute-Valueパラダイムのバージョンを実装しました(私はeav-djangoを試しましたが、それは十分に柔軟ではありませんでした)。私のモデルではProduct-Parameter-Value(下記のEditを参照)です。 パラメータと値のペアに管理者インラインを含めると、すべての値に対して同じ入力フォームフィールドが使用されることを除いて、すべてが機能します。私はこれがデフォルトのDjango管理者の動作であることを理解しています。なぜなら、各インライン行に対して同じフォームセットを使用するからです。
パラメータ(get_value_formfield)にコールバックがあります。私は現在:
class SpecificationValueAdminInline(admin.TabularInline):
model = SpecificationValue
fields = ('parameter', 'value')
readonly_fields = ('parameter',)
max_num = 0
def get_formset(self, request, instance, **kwargs):
"""Take a copy of the instance"""
self.parent_instance = instance
return super().get_formset(request, instance, **kwargs)
def formfield_for_dbfield(self, db_field, **kwargs):
"""Override admin function for requesting the formfield"""
if self.parent_instance and db_field.name == 'value':
# Notice first() on the end -->
sv_instance = SpecificationValue.objects.filter(
product=self.parent_instance).first()
formfield = sv_instance.parameter.get_value_formfield()
else:
formfield = super().formfield_for_dbfield(db_field, **kwargs)
return formfield
を持っています。フォームフィールドは、管理ページごとに1回だけ呼び出されます。
formfield_for_dbfieldが各SpecificationValueインスタンスに対して一度呼び出されるように、デフォルトでの動作をオーバーライドする方法はありますか?
編集:私は最終的に、これは管理インラインのform =
属性を使用している解決
class Product(Model):
specification = ManyToManyField('SpecificationParameter',
through='SpecificationValue')
class SpecificationParameter(Model):
"""Other normal model fields here"""
type = models.PositiveSmallIntegerField(choices=TUPLE)
def get_value_formfield(self):
"""
Return the type of form field for parameter instance
with the correct widget for the value
"""
class SpecificationValue(Model):
product = ForeignKey(Product)
parameter = ForeignKey(SpecificationParameter)
# To store and retrieve all types of value, overrides CharField
value = CustomValueField()