除非选中,否则使用BooleanField的Django表单总是无效的
我有一个使用以下forms的应用程序:
class ConfirmForm(forms.Form): account_name = forms.CharField(widget=forms.HiddenInput) up_to_date = forms.BooleanField(initial=True)
我使用下面的模板exerpt中的表单:
<form class="confirmform" action="/foo/" enctype="multipart/form-data" method="post"> {{ confirm_form.up_to_date }} Check if this data brings the account up to date.<br> {{ confirm_form.account_name }} <input type="submit" name="confirm" value="Confirm" /> </form>
我的看法使用以下基本的代码结构:
if request.method == 'POST': #check for 'confirm' because I actually have multiple forms in this page if 'confirm' in request.POST: confirm_form = ConfirmForm(request.POST) if confirm_form.is_valid(): #do stuff else: c['confirm_form'] = confirm_form else: c['confirm_form'] = ConfirmForm({'account_name':'provided_value'})
有两件事是错误的:
1)即使我有初始=真,checkbox未加载页面加载时
2)除非我检查checkbox,否则表格总是无效的。 它仅给up_to_date提供错误:“此字段是必需的。”
我已经阅读了这个类似的问题,但他的解决scheme不适用于我的项目。
发生什么了?
编辑:
我更新了上面的代码,以更忠实于我的实际代码。
问题#1是我的错,因为当表单被实例化时,我通过绑定数据覆盖了初始值。
问题2我仍然在考虑一个问题。 在up_to_date
上使用required=False
可以解决问题,但是使用默认的小部件似乎不正确,但是BooleanField
可以是NULL
(导致有效性检查失败),也可以是True
但不会是False
。
initial=True
应该使用checked="checked"
来呈现小部件,所以我没有看到那里的问题..但是表单无效的原因是因为所有的字段都是默认情况下需要的,除非您另外指定。
Field.required¶默认情况下,每个Field类都假定这个值是必需的,所以如果你传递一个空的值 – None或者空string(“”) – 那么clean()会引发一个ValidationErrorexception:
如果您希望checkbox或任何其他值是可选的,则需要将required=False
传递到表单字段构造函数中。
up_to_date = forms.BooleanField(initial=True, required=False) # no longer required..
在Django窗体中,必须使用required=False
创build布尔字段。
当checkbox未选中时,浏览器不会在请求的POST参数中发送字段。 没有指定该字段是可选的,当不在POST参数中时,Django会将其视为缺失字段。
Imho这将是很好的Django具有默认情况下布尔表单域的这种行为..
(Yuji的评论已经回答了这个问题,但作为答案是有用的)
根据官方文件 :
如果你想在你的表单中包含一个可以是
True
或False
的布尔值(例如checked或unchecked checkbox),你必须记住在创buildBooleanField时必须传入required=False
。
确保在第一次加载页面时不会覆盖初始表单。
我原来并没有检查request.GET中是否有任何实际的东西。 第一次页面加载request.GET是无,并调用SomeForm(request.GET)实际上会消除初始值。
def some_view(request): form = SomeForm() if request.method == 'GET': form = SomeForm(request.GET)
添加一个检查,以确保有request.GET中解决这个问题。
def some_view(request): form = SomeForm() if request.method == 'GET' and request.GET: form = SomeForm(request.GET)