【问题标题】:Specifying widget for model form extra field (Django)为模型表单额外字段指定小部件(Django)
【发布时间】:2012-08-19 08:01:55
【问题描述】:

我必须在我的模型表单中添加额外的字段。我的做法是:

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'}),
        }

但似乎 class Meta 处的 extra_field 的小部件定义被忽略了,因为我在模板上有一个裸 input 标签而不是 textarea。 所以我采用下一种方法:

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

它非常适合我,但我曾经在 class Meta 声明中为表单字段指定小部件。所以我想知道:

为什么我的第一种方法不起作用?我做错了什么?

【问题讨论】:

  • 你确定你使用的是 Django 1.4 吗? Form.Meta.widgets 是在 Django 1.4 中引入的。

标签: python django django-forms extra


【解决方案1】:

如果它是一个额外的字段并不重要。这有效:

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'}),
        }

这是not documented indeed,这是我在可能与该行为相关的文档中找到的最好的(也许不是,这只是我能找到的最好的):

如果你像这样显式实例化一个表单域,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 更新为 declared_fields,fields['name'].widget 变为 django.forms.widgets.TextInput,这是 CharField 的默认值。

显然,明确的字段定义具有优先权。

感谢您的提问,很高兴知道,很好的问题。

【讨论】:

  • 这个答案对我不起作用。也许 django 改变了行为
  • 这应该仍然有效,也许再提出一个问题?
【解决方案2】:

我用以下方法解决了上述情况:

class FooForm(forms.ModelForm):
    name = forms.CharField(widget=TextArea(attrs={'placeholder': u'Bla bla'}))
    class Meta:
        model = People

【讨论】:

  • 这是否也将字段名称添加到表中?
猜你喜欢
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 2017-04-02
  • 1970-01-01
  • 2018-07-18
  • 2015-06-13
  • 1970-01-01
  • 2015-10-06
相关资源
最近更新 更多