我对Django很新,我正在使用Django 1.0。
我有这个:
forms.py:
class MyForm(forms.Form):
extra_cheeze = forms.BooleanField(required=False,
initial=False,
label='Extra cheeze')
views.py:
def order_something(request):
form = MyForm(request.POST or None)
if request.method == 'POST' and form.is_valid():
# do stuff...
问题是除非选中复选框,否则表单无效,因此似乎没有办法从字段中获取False值。 据我所知the docs,它应该有效。如果我将CharField添加到表单中,它就可以工作......
我在这里误解了什么,或者这是一个错误? (是的,我用Google搜索但没有发现任何相关内容)
更新:正如@Dominic Rodger建议的那样,我尝试添加隐藏字段
dummy = forms.CharField(initial='dummy', widget=forms.widgets.HiddenInput())
这使表格有效。这种解决方法使我现在可以继续前进,但知道我是否误解了某些内容仍然很有趣......
答案 0 :(得分:9)
我的问题中的代码中存在错误。感谢@ d0ugal通过包含一个稍微不同的例子帮助我发现它。问题出在这里:
form = MyForm(request.POST or None) # <- PROBLEM HERE!!!!!!!!!!!!!!!!
if request.method == 'POST' and form.is_valid():
# do stuff...
错误是我假设request.POST如果是帖子则评估为True。但是由于浏览器没有为未选中的复选框发布任何内容,并且这是唯一的字段,因此POST数据是一个空字典,其结果为False。这导致None被用作初始化数据,导致表单未绑定且无效 @ d0ugal的例子做了安全的事情并首先测试request.method。
答案 1 :(得分:4)
这对我来说也适用于1.1,1.0.3和1.0(我有三个虚拟环境设置)。我只在FireFox中测试了这个,所以如果它的浏览器问题是另一个问题,但据我所知他们都处理POST数据与复选框相同。
以下是该项目的完整代码,以便您可以在闲暇时重现并与您的产品进行比较,以了解其中的差异。
在Ubuntu中设置
$ django-admin.py startproject testing
$ cd testing/
$ python manage.py startapp myfirst
然后在myfirst app文件夹中;
<强> /myfirst/views.py 强>
from django.shortcuts import render_to_response
from myfirst.forms import MyForm
def testing(request):
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
result = "valid"
else:
result = "not valid"
else:
form = MyForm()
result = "no post"
return render_to_response('test.html', {'form':form, 'result':result,})
<强> /myfirst/forms.py 强> 来自django进口表格
class MyForm(forms.Form):
extra_cheeze = forms.BooleanField(required=False,initial=False,label='Extra cheeze')
<强> /myfirst/templates/test.html 强>
<html>
<head>
</head>
<body>
<form action="." method="POST">
{{ form }}
<input type="submit" value="test">
</form>
{{ result }}
</body>
</html>
<强> /urls.py 强> 来自django.conf.urls.defaults import *
from myfirst.views import testing
urlpatterns = patterns('',
(r'.*', testing),
)
然后运行项目$ python manage.py runserver并浏览到http://localhost:8000/。您实际上会发现所需的对复选框没有任何作用,因为您不能将其留空 - “空白”答案实际上是“不”。如果您想确保用户选择答案,可以选择是或否。你也可以强迫他们用单选按钮回答。
答案 2 :(得分:0)
这不是答案,它仅描述Django的行为。
Python 3.8.4rc1上的Django 3.0.7,Debian 10 /测试。
我的场景是html <form>
,其中包含更多的django表单。表单中呈现了类,其中一个仅包含BooleanField。 (页面中还有其他小的<forms>
,例如搜索表单)。
class OrderInvoiceTypeForm(forms.Form):
is_business = forms.BooleanField(label="business", initial=False) # with or without required=False
我通过“提交”按钮提交,该按钮不在OrderInvoiceTypeForm中,但在html中。
with required = False格式始终有效,并且is_business密钥位于.cleaned_data中。
不需要(或使用= True):
已选中:
form_with_boolean.is_valid() # True
form_with_boolean.cleaned_data # {'is_business': True}
未选中:
form_with_boolean.is_valid() # False
form_with_boolean.cleaned_data # {}
在第二种情况下,在开发工具中,我可以看到浏览器(Chrome)没有发送is_business值POST变量。添加隐藏字段将无济于事。