3

我完全被困在这里。为什么这个测试用例会失败?

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())

它无法通过表单字段验证,但前提是当我更新 QueryDict 时 bogus_bool 为 False。如果我说:

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

然后它通过验证。这里发生了什么?这是 Django 表单中的错误吗?

如果在将 QueryDict 传递给 BogusForm 构造函数之前查看它,它看起来像这样:

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

这对我来说看起来完全合法和正确。

4

3 回答 3

3

来自 django 的文档

由于所有的 Field 子类默认都有 required=True ,所以这里的验证条件很重要。如果您想在表单中包含一个可以为 True 或 False 的布尔值(例如选中或未选中的复选框),您必须记住在创建 BooleanField 时传入 required=False。

于 2012-05-04T00:16:36.213 回答
2

我同意这是不正确的行为。

这应该适用于特定领域:

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]


这应该对表单上的所有 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)

有一种方法可以通过不需要required=False布尔字段上的那个位来使其变得更好,但目前不值得付出努力。

于 2013-03-29T21:51:10.867 回答
0

这是因为您的 bogus_bool 默认情况下是必填字段。

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

应该做的伎俩。

于 2012-05-04T00:01:55.277 回答