AssertionError:full_clean未引发ValidationError

问题描述 投票:0回答:2

以下面的形式,我声明了一个clean()方法,该方法正在评估以下条件:

expiration_datecreated_date之前吗?

如果该条件为True,我想提出一个ValidationError。运行测试时,出现以下错误:AssertionError: ValidationError not raised by full_clean

但是如果调用form.errors.as_data(),则会导致:{'expiration_date': [ValidationError(['The expiration date is set before the created date'])]}

有人可以解释发生了什么吗?

forms.py

class MenuForm(forms.ModelForm):
    MENU_YEARS = [2019, 2020, 2021]

    season = forms.CharField(
        min_length=4, 
        validators=[validate_season]
    )
    items = forms.ModelMultipleChoiceField(
        queryset=Item.objects.all(),
        to_field_name='name'
    )
    expiration_date = forms.DateTimeField(
        required=False,
        widget=SelectDateWidget(
            years=MENU_YEARS,
            empty_label=("Choose Year", "Choose Month", "Choose Day")
        )
    )

    def clean(self):
        cleaned_data = super().clean()
        created_date = cleaned_data['created_date'] = timezone.now()
        expiration_date = cleaned_data['expiration_date']
        if created_date > expiration_date:
            raise ValidationError(
               {'expiration_date': "The expiration date is set before the created date"}
            )

    class Meta:
        model = Menu
        fields = ['season', 'items', 'expiration_date']

test_forms.py

class TestMenuForm(TestCase):

    @classmethod
    def setUpTestData(cls):
        cls.data = {
            'season': 'Late Fall',
            'items': ['Crepe'],
            'expiration_date': datetime(2018, 1, 2)
        }

    def test_menu_model_clean(self):
        with self.assertRaises(ValidationError):
            self.menu_form.full_clean()
python django unit-testing django-forms
2个回答
1
投票

尽管@Marcell答案是有效的,但我不认为这是您所遇到的行为的原因。

据我所知,在full_clean上调用ModelForm时也会调用clean方法,但是ValidationErrors在内部被捕获,并且错误被添加到form.errors。因此,您的测试不会“看到”此错误。这就是您当前在测试中看到的内容。恕我直言,此行为很有意义,因为您可能不希望您的应用因验证错误而停止。

要测试您的ValidationError,您可能希望直接调用clean表单而不是full_clean形式。


0
投票

您需要返回清除的数据

def clean(self):
    cleaned_data = super().clean()
    created_date = cleaned_data['created_date'] = timezone.now()
    expiration_date = cleaned_data['expiration_date']
    if created_date > expiration_date:
        raise ValidationError(
           {'expiration_date': "The expiration date is set before the created date"}
        )
    return cleaned_data
© www.soinside.com 2019 - 2024. All rights reserved.