简体   繁体   English

Django Forms BooleanField单元测试用例有什么问题?

[英]What is wrong with the Django Forms BooleanField unit test case?

I'm totally stuck here. 我完全被困在这里了。 Why does this test case fail? 为什么这个测试用例失败了?

class BogusForm(forms.Form):
    bogus_bool = forms.BooleanField() 

class TestBogusForm(TestCase):

    def test_bogus_false(self):
        query_dict = QueryDict('', mutable=True)
        query_dict.update({'bogus_bool': False})
        bogus_form = BogusForm(query_dict)
        self.assertTrue(bogus_form.is_valid())

It fails form field validation, but only if bogus_bool is False when I update the QueryDict . 它失败了表单字段验证, 但只有当我更新QueryDict时bogus_bool为False If I say: 如果我说:

query_dict.update({'bogus_bool': True})

Then it passes validation. 然后它通过验证。 What's going on here? 这里发生了什么? Is this a bug in Django Forms? 这是Django Forms中的错误吗?

If I look at the QueryDict before I pass it to the BogusForm constructor, it looks like this: 如果我在将它传递给BogusForm构造函数之前查看QueryDict,它看起来像这样:

<QueryDict: {u'bogus_bool': [False]}>

Which looks totally legit and correct to me. 这对我来说看起来完全合法和正确。

From django's documentation 来自django的文档

Since all Field subclasses have required=True by default, the validation condition here is important. 由于默认情况下所有Field子类都必须为= True,因此此处的验证条件很重要。 If you want to include a boolean in your form that can be either True or False (eg a checked or unchecked checkbox), you must remember to pass in required=False when creating the BooleanField. 如果要在表单中包含一个可以为True或False的布尔值(例如,选中或未选中复选框),则必须记住在创建BooleanField时传入required = False。

I agree that this is incorrect behavior. 我同意这是不正确的行为。

This should do for a specific field: 这应该针对特定领域:

class BogusForm(forms.Form):
    bogus_bool = forms.BooleanField(required=False)

    def clean_bogus_bool(self):
        field_name = 'bogus_bool'
        if field_name not in self.data:
            raise forms.ValidationError("This field is required.")
        return self.cleaned_data[field_name]


This should do it for all bool fields on the form: 这应该对表单上的所有bool字段执行:

class BooleanFieldsRequiredMixin(forms.Form):
    def clean(self):
        for field_name, field in self.fields.iteritems():
            # Only BooleanField not subclasses of it.
            if type(field) is not forms.BooleanField:
                continue

            if field_name not in self.data:
                self._errors[field_name] = self.error_class(["This field is required."])

        return super(BooleanFieldsRequiredMixin, self).clean()


class BogusForm(BooleanFieldsRequiredMixin, forms.Form):
    bogus_bool = forms.BooleanField(required=False)

There is a way to make this nicer by not requiring that required=False bit on the boolean field, but it's not worth the effort at the moment. 有一种方法可以通过不要求布尔字段上的required=False来使这个更好,但是目前不值得努力。

It's because your bogus_bool is a required field by default. 这是因为默认情况下你的bogus_bool是必填字段。

class BogusForm(forms.Form):
    bogus_bool = forms.BooleanField(required=False)

should do the trick. 应该做的伎俩。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM