除非选中,否则带有布尔字段的Django表单始终无效
我有一份使用以下表格的申请:除非选中,否则带有布尔字段的Django表单始终无效,django,django-forms,Django,Django Forms,我有一份使用以下表格的申请: class ConfirmForm(forms.Form): account_name = forms.CharField(widget=forms.HiddenInput) up_to_date = forms.BooleanField(initial=True) 我使用以下模板练习中的表格: <form class="confirmform" action="/foo/" enctype="multipart/form-data" met
class ConfirmForm(forms.Form):
account_name = forms.CharField(widget=forms.HiddenInput)
up_to_date = forms.BooleanField(initial=True)
我使用以下模板练习中的表格:
<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>
有两件事是错误的:
1) 即使我有initial=True,当页面加载时复选框也会被取消选中
2) 除非我选中复选框,否则表单始终无效。它只提供最新的错误:“此字段是必需的。”
我读过,但他的解决方案不适用于我的项目
所以。。。发生什么事了
编辑:
我更新了上面的代码,以更加忠实于我的实际代码
问题#1是我的错,因为在实例化表单时,我通过绑定数据覆盖了初始值
问题2我仍然考虑一个问题。使用
required=False
onup\u-date
可以解决问题,但是使用默认小部件,BooleanField
可以是NULL
(导致有效性检查失败)这似乎并不正确或者True
但决不False
initial=True
应使用checked=“checked”
呈现小部件,因此我看不出存在问题。。但是表单无效的原因是,除非您另行指定,否则默认情况下所有字段都是必需的
默认情况下,每个字段类都假定该值为
必需,因此如果您传递一个空值——None或empty
字符串(“”)——然后clean()将引发ValidationError异常:
如果希望复选框或任何其他值是可选的,则需要将required=False
传递到表单字段构造函数中
up_to_date = forms.BooleanField(initial=True, required=False)
# no longer required..
确保第一次加载页面时没有覆盖初始表单 我最初没有检查request.GET中是否有任何内容。页面第一次加载request.GET时为None,调用SomeForm(request.GET)实际上会清除初始值
def some_view(request):
form = SomeForm()
if request.method == 'GET':
form = SomeForm(request.GET)
正在添加检查以确保请求中有内容。请修复此问题
def some_view(request):
form = SomeForm()
if request.method == 'GET' and request.GET:
form = SomeForm(request.GET)
在Django表单中,必须使用
required=False
创建布尔字段
如果未选中该复选框,浏览器不会发送请求的POST参数中的字段。如果不指定该字段为可选字段,Django将在不在POST参数中时将其视为缺少的字段
对于Django来说,对于布尔形式的字段,默认情况下有这样的行为是很好的
(这已经在Yuji的评论中得到了回答,但作为一个回答,它将是有用的)根据:
如果希望在表单中包含布尔值,该布尔值可以是True
或False
(例如,选中或未选中的复选框),则在创建布尔字段时必须记住传入required=False
如果您按照建议执行,则您的最新字段可能总是错误的。你永远不会知道这是因为用户希望这样做,还是因为用户跳过了字段 我也有同样的问题与法律要求的选择_的问题。在注册时,我需要让用户做出良心决定,允许我的系统向他们发送未经请求的电子邮件(或不发送)。我正在使用Django Allauth和一个自定义用户数据库 我将在下面分享我的解决方案,希望您能根据自己的情况调整它-我从中调整了它 forms.py:
# ExtraFieldsSignup as per https://stackoverflow.com/a/12308807
class SignupFormExtraFields(forms.Form):
CHOICES = (('1', 'YES, keep in touch',), ('2', 'No',))
first_name = forms.CharField(max_length=30, label='Voornaam')
last_name = forms.CharField(max_length=30, label='Achternaam')
opt_in = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES)
def signup(self, request, user):
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
# Now we figure out what the user chose:
if self.cleaned_data['opt_in'] == '1':
user.opt_in = True
else:
user.opt_in = False
user.save()
只是一种预感,但这可能是基本的——在意识到类似的东西只是基本的变量类型之前,我们浪费了几个小时 在我的例子中,在创建表单之后(非常基本,请参见下文) 。。。我在用 如果选择=='True': .. 在我看来。但由于表单使用的是布尔值,正确的代码应该是: 如果选择为真:
第一行永远不会工作,因为“==”不用于布尔类型。希望不是这样,但我想在这里标记它,因为我一直在互联网上尝试和搜索,没有注意我使用的变量类型。尽管如此,initial=True没有效果。另外,为什么解决方案是将字段设置为可选?BooleanField不能返回false吗?HTML是否以“checked”呈现?你重启服务器了吗?您是否可以在此时启动调试器(
import pdb;pdb.set_trace()
),以再次检查初始属性是否设置正确assert form.fields['up\u to\u date'].initial==True
这些将缩小我们的问题范围..至于为什么要将该字段设置为可选字段?1:医生这么说。但是2:复选框是HTML元素,在“未选中”时不会提交数据。False
值只能通过缺少输入来确定?不要说这样的话。(2) 没错!我现在明白了我需要做什么才能让它工作,但我不知道为什么设计师会允许is_valid()失败,而我们想要的是一个错误的结果。可能是文档应该告诉我们总是让'required=False',除非小部件或验证器被更改。当你想要一个错误的结果时,为什么设计者会允许is\u valid()
失败?我不明白这里的问题。在您当前的代码示例中,它不允许抛出验证错误的False
结果。
# ExtraFieldsSignup as per https://stackoverflow.com/a/12308807
class SignupFormExtraFields(forms.Form):
CHOICES = (('1', 'YES, keep in touch',), ('2', 'No',))
first_name = forms.CharField(max_length=30, label='Voornaam')
last_name = forms.CharField(max_length=30, label='Achternaam')
opt_in = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES)
def signup(self, request, user):
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
# Now we figure out what the user chose:
if self.cleaned_data['opt_in'] == '1':
user.opt_in = True
else:
user.opt_in = False
user.save()
class para_selection(forms.Form):
first=forms.BooleanField(initial=False, required=False)
second=forms.BooleanField(initial=False, required=False)
third=forms.BooleanField(initial=False, required=False)
fourth=forms.BooleanField(initial=False, required=False)