django表单:绑定表单的默认值
使用此表格:django表单:绑定表单的默认值,django,forms,Django,Forms,使用此表格: class Form(forms.Form): name = forms.CharField(required=False, initial='Hello world') 如果我在视图中执行类似操作: form = Form(request.GET) if form.is_valid(): name = form.cleaned_data['name'] 然后,即使request.GET不包含name作为键,名称的初始值也会丢失。有什么解决办法吗?我希望将初始值
class Form(forms.Form):
name = forms.CharField(required=False, initial='Hello world')
如果我在视图中执行类似操作:
form = Form(request.GET)
if form.is_valid():
name = form.cleaned_data['name']
然后,即使request.GET不包含
name
作为键,名称的初始值也会丢失。有什么解决办法吗?我希望将初始值作为“默认值”绑定到表单中。initial
并不是用来为表单字段设置默认值的。
相反,在向用户显示表单时,它实际上更像是一个占位符实用程序,如果不需要该字段,它将无法正常工作(如您的示例中所示)
您可以做的是检查该字段是否有空值并返回默认值的方法:
class Form(forms.Form):
name = forms.CharField(required=False, initial='Hello world')
def clean_name(self):
name = self.cleaned_data['name']
if name is None:
return self.fields['name'].initial
return name
request.GET
是一个类似字典的对象
initial
仅在未绑定表单的情况下有效
表单有一个名为data
的属性。在表单初始化期间,此属性作为第一个位置参数或数据
关键字参数提供
绑定表单是指您提供一些数据作为表单的第一个参数,而未绑定表单的data
属性设置为None的表单
在初始化表单form=form(request.GET)
时,您提供了第一个位置参数,因此在表单上设置了data
属性,它将成为绑定表单。即使request.GET
是空字典,也会发生这种情况。由于表单成为绑定表单,因此name
字段的initial
对其没有影响
因此,在您收到请求时,您应该:
form = Form()
您的姓名
字段的首字母
将获得奖励
或者,如果您想从request.GET中读取name
,如果它在那里,那么您想使用它而不是字段的首字母,那么在您的视图中有以下内容
name = request.GET.get(name)
form_level_initial = {}
if name:
form_level_initial['name'] = name
form = Form(initial=form_level_initial)
这是否有效:
initial_form_data = {'name': 'Hello World'} #put all the initial for fields in this dict
initial_form_data.update(request.GET) #any field available in request.GET will override that field in initial_form_data
form = Form(initial_form_data)
if form.is_valid():
name = form.cleaned_data['name']
通过稍微修改Gonzalo的解决方案,这是正确的方法:
class Form(forms.Form):
name = forms.CharField(required=False, initial='Hello world')
def clean_name(self):
if not self['name'].html_name in self.data:
return self.fields['name'].initial
return self.cleaned_data['name']
如果你需要这个,你可以看看django过滤器应用程序。我最近发现了它。我使用以下模式设置默认值作为表单的初始值-
class InitialDefaultForm(forms.Form):
def clean(self):
cleaned_data = super(InitialDefaultForm, self).clean()
# if data is not provided for some fields and those fields have an
# initial value, then set the values to initial value
for name in self.fields:
if not self[name].html_name in self.data and self.fields[name].initial is not None:
cleaned_data[name] = self.fields[name].initial
return cleaned_data
这确保了所有具有初始值但未从用户处获取值的字段都由其初始值填充。没有一个答案真正符合clime的要求。下面是我对同样问题的解决方案:
class LeadsFiltersForm(forms.Form):
TYPE_CHOICES = Lead.TYPES
SITE_CHOICES = [(site.id, site.name) for site in Site.objects.all()]
type = forms.MultipleChoiceField(
choices=TYPE_CHOICES, widget=forms.CheckboxSelectMultiple(),
required=False
)
site = forms.MultipleChoiceField(
widget=forms.CheckboxSelectMultiple(), required=False,
choices=SITE_CHOICES
)
date_from = forms.DateField(input_formats=['%m-%d-%Y',], required=False,
widget=forms.TextInput(attrs={'placeholder': 'Date From'}),
initial=timezone.now() - datetime.timedelta(days=30))
date_to = forms.DateField(input_formats=['%m-%d-%Y',], required=False,
widget=forms.TextInput(attrs={'placeholder': 'Date To'}))
defaults = {
'type': [val[0] for val in TYPE_CHOICES],
'site': [val[0] for val in SITE_CHOICES],
'date_from': (timezone.now() - datetime.timedelta(days=30)).strftime('%m-%d-%Y'),
'date_to': timezone.now().strftime('%m-%d-%Y')
}
def __init__(self, data, *args, **kwargs):
super(LeadsFiltersForm, self).__init__(data, *args, **kwargs)
self.data = self.defaults.copy()
for key, val in data.iteritems():
if not data.get(key):
continue
field = self.fields.get(key)
if field and getattr(field.widget, 'allow_multiple_selected', False):
self.data[key] = data.getlist(key)
else:
self.data[key] = data.get(key)
提出的解决方案要么对我不起作用,要么看起来不太优雅。文档规定,初始值不适用于绑定表单,它似乎是原始提问者(和我的)用例: 这就是为什么仅为未绑定表单显示初始值的原因。对于绑定表单,HTML输出将使用绑定数据 我的解决方案是查看表单是否应绑定:
initial = {'status': [Listing.ACTIVE], 'min_price': 123} # Create default options
if request.method == 'GET':
# create a form instance and populate it with data from the request:
if len(request.GET):
form = ListingSearchForm(request.GET) # bind the form
else:
form = ListingSearchForm(initial=initial) # if GET is empty, use default form
您还可以使用初始化表单的其他方法(如上所述) 这是一个有趣的选项,但如果不是名称:,则存在问题。如果在request.GET中设置了
name
,但设置为空字符串,该怎么办。在这种情况下,空字符串将被覆盖。我认为这是您想要的行为,我正在编辑我的答案以处理这种情况:-)name
将永远不会为空。即使在request.GET中未设置name
,cleaned_data['name']
也将是空字符串,因为name是CharField。如果name
在request.GET中作为空字符串发送,它无论如何都是一个空字符串。因此,您无法区分这两种情况。抱歉,我没有提到我需要在表单中显示默认值/初始值。如果请求未覆盖,则验证后需要清理的\u数据。GETcleaned\u数据和验证应在请求后生成,而不是在GET时生成。你能再解释一下你想要什么吗?这似乎是一个优雅的解决方案,但在我的例子中,它将u“”之类的东西放入表单中,然后触发了验证错误(我在下面提出了一个替代答案,可以绕过这个问题。