我有CharField
的Django ModelForm,其中包含一组choices
。我想为用户提供四个输入:我希望三个选项具有多个选项,最后一个是自由文本输入字段。有没有办法用一个具有两种不同输入样式的Field渲染一个ModelForm
?
答案 0 :(得分:1)
我认为您正在寻找修改模型表单中使用的小部件。记录here已经很好了。但是,这是一个快速的例子,应该是你正在寻找的。 p>
class ExampleForm(forms.ModelForm):
field_1 = forms.CharField(widget=forms.SelectMultiple(choices=FIELD_1_CHOICES))
field_2 = forms.CharField(widget=forms.SelectMultiple(choices=FIELD_2_CHOICES))
field_3 = forms.CharField(widget=forms.SelectMultiple(choices=FIELD_3_CHOICES))
field_4 = forms.CharField(widget=forms.TextInput())
class Meta:
model = ExampleModel
fields = ['field_1', 'field_2', 'field_3', 'field_4']
您需要为每个字段定义FIELD_1_CHOICES,并提供您想要提供的任何选项。此外,您不必为field_4执行该行,因为TextInput
是CharField
的默认小部件,但我将其添加为明确。
答案 1 :(得分:1)
你可以使用这个自定义小部件来解决问题,HTML5允许你有一个带有下拉列表的自由文本输入,它可以作为一个选择或写入其他类型的字段,这就是我制作的方式它:
fields.py
from django import forms
class ListTextWidget(forms.TextInput):
def __init__(self, data_list, name, *args, **kwargs):
super(ListTextWidget, self).__init__(*args, **kwargs)
self._name = name
self._list = data_list
self.attrs.update({'list':'list__%s' % self._name})
def render(self, name, value, attrs=None):
text_html = super(ListTextWidget, self).render(name, value, attrs=attrs)
data_list = '<datalist id="list__%s">' % self._name
for item in self._list:
data_list += '<option value="%s">' % item
data_list += '</datalist>'
return (text_html + data_list)
forms.py
from myapp.fields import FormForm
class FormForm(forms.Form):
char_field_with_list = forms.CharField(required=True)
def __init__(self, *args, **kwargs):
_country_list = kwargs.pop('data_list', None)
super(FormForm, self).__init__(*args, **kwargs)
# the "name" parameter will allow you to use the same widget more than once in the same
# form, not setting this parameter differently will cuse all inputs display the
# same list.
self.fields['char_field_with_list'].widget = ListTextWidget(data_list=_data_list, name='country-list')
views.py
from myapp.forms import FormForm
def country_form(request):
# instead of hardcoding a list you could make a query of a model, as long as
# it has a __str__() method you should be able to display it.
country_list = ('Mexico', 'USA', 'China', 'France')
form = FormForm(data_list=country_list)
return render(request, 'my_app/country-form.html', {
'form': form
})