27

モデル フォームにフィールドを追加する必要があります。私のアプローチは次のとおりです。

class MyForm(forms.ModelForm):
    extra_field = forms.CharField()
    class Meta:
        model = MyModel
        widgets = {
            #Does not work
            'extra_field': forms.Textarea(attrs={'placeholder': u'Bla bla'}),
        }

しかし、テンプレートにテキストエリアの代わりに裸の入力タグがあるため、 extra_fieldatのウィジェット定義は無視されているようです。だから私は次のアプローチを適用します:class Meta

class MyForm(forms.ModelForm):
    #It works fine
    extra_field = forms.CharField(widget=forms.Textarea())
    class Meta:
        model = MyModel

私にとっては完璧に機能しますが、class Meta宣言時にフォームフィールドのウィジェットを指定していました。だから私は疑問に思います:

最初のアプローチがうまくいかないのはなぜですか? 私が間違っていることは何ですか?

4

2 に答える 2

34

それが余分なフィールドであるかどうかは問題ではありません。これは機能します:

class FooForm(forms.ModelForm):
    class Meta:
        model = People
        widgets = { 
            'name': forms.Textarea(attrs={'placeholder': u'Bla bla'}),
        }   

これはしません:

class FooForm(forms.ModelForm):
    name = forms.CharField()

    class Meta:
        model = People
        widgets = { 
            'name': forms.Textarea(attrs={'placeholder': u'Bla bla'}),
        }

これは実際には文書化されていません。これは、その動作に関連する可能性のあるドキュメントで見つけることができる最高のものです(そうではないかもしれませんが、私が見つけた最高のものです):

このようにフォーム フィールドを明示的にインスタンス化すると、Django はその動作を完全に定義する必要があると想定します[...]フォーム フィールドを宣言するときに、関連する引数を明示的に設定する必要があります

この動作の実装は、django/forms/models.py の 219 行目です。

   204         if opts.model:
   205             # If a model is defined, extract form fields from it.
   206             fields = fields_for_model(opts.model, opts.fields,
   207                                       opts.exclude, opts.widgets, formfield_callback)
   208             # make sure opts.fields doesn't specify an invalid field
   209             none_model_fields = [k for k, v in fields.iteritems() if not v]
   210             missing_fields = set(none_model_fields) - \
EE 211                              set(declared_fields.keys())
   212             if missing_fields:
   213                 message = 'Unknown field(s) (%s) specified for %s'
   214                 message = message % (', '.join(missing_fields),
   215                                      opts.model.__name__)
   216                 raise FieldError(message)
   217             # Override default model fields with any custom declared ones
   218             # (plus, include all the other declared fields).
   219             fields.update(declared_fields)

206 行目以降の fields['name'].widget、Meta.widgets で指定された Textarea です。

219 行目で、fields が defined_fields で更新され、fields['name'].widget が CharField のデフォルトである django.forms.widgets.TextInput になります。

どうやら、明示的なフィールド定義が優先されます。

お問い合わせいただきありがとうございます。よい質問です。

于 2012-08-23T18:28:32.167 に答える