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 Forms のバグですか?

BogusForm コンストラクターに渡す前に QueryDict を見ると、次のようになります。

<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 に答える