Django形式只有一个BooleanField

时间:2009-10-12 11:56:02

标签: django django-forms

我对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())
这使表格有效。这种解决方法使我现在可以继续前进,但知道我是否误解了某些内容仍然很有趣......

3 个答案:

答案 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变量。添加隐藏字段将无济于事。