2016-09-14 1 views
0

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() 

答えて

0

方法:

ここでは、モデルのレイアウトです。このような標準的なフォーム、選択肢(例えばRadioSelectCheckboxSelectMultiple<ul>が持っていないため、管理インターフェイスに横にリストの弾丸を持っているとのウィジェットを使用して

class SpecificationValueForm(ModelForm): 
    class Meta: 
     model = SpecificationValue 

    def __init__(self, instance=None, **kwargs): 
     super().__init__(instance=instance, **kwargs) 
     if instance: 
      self.fields['value'] = instance.parameter.get_value_formfield() 
     else: 
      self.fields['value'].disabled = True 

class SpecificationValueAdminInline(admin.TabularInline): 
    form = SpecificationValueForm 

:これはModelAdminののフォーム生成コードをスキップradiolistクラス。あなたはAdminRadioSelect(attrs={'class': 'radiolist'})を使用してRadioSelectをほぼ修正できますが、CheckboxSelectMultipleの管理者バージョンはありませんので、私は一貫性を優先しました。また、<fieldset>ラッパー要素には、alignedクラスがありません。

私はそれに生きなければならないように見えます!

関連する問題