Указание виджета для дополнительного поля формы модели (Django)
Я должен добавить дополнительное поле в форму модели. Мой подход:
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_field
в class Meta
игнорируется, потому что у меня есть пустой тег ввода вместо textarea в шаблоне. Поэтому я применяю следующий подход:
class MyForm(forms.ModelForm):
#It works fine
extra_field = forms.CharField(widget=forms.Textarea())
class Meta:
model = MyModel
Это прекрасно работает для меня, но я использовал, чтобы указать виджеты для полей формы в class Meta
декларация. Так что мне интересно
Почему мой первый подход не работает? Что я делаю не так?
2 ответа
Неважно, если это дополнительное поле. Это работает:
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 предполагает, что вы хотите полностью определить его поведение [...], вы должны явно указать соответствующие аргументы при объявлении поля формы.
Реализация этого поведения находится в строке 219 django / forms / models.py:
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.
В строке 219 поля обновляются с помощью объявленных полей и полей ['name']. Widget становится django.forms.widgets.TextInput, который является значением по умолчанию для CharField.
Очевидно, что явные определения полей имеют приоритет.
Спасибо за вопрос, полезно знать, отличный вопрос.
Я решил ситуацию выше с помощью следующего:
class FooForm(forms.ModelForm):
name = forms.CharField(widget=TextArea(attrs={'placeholder': u'Bla bla'}))
class Meta:
model = People