在以下形式中,我声明了一个clean()
方法,该方法正在评估以下条件:
expiration_date
在created_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()
答案 0 :(得分:1)
尽管@Marcell答案是有效的,但我认为这不是您所遇到的行为的原因。
据我所知,在full_clean
上调用ModelForm
时也会调用clean
方法,但是ValidationErrors
在内部被捕获,错误被添加到{{ 1}}。因此,您的测试不会“看到”此错误。这就是您当前在测试中看到的内容。恕我直言,此行为很有意义,因为您可能不希望您的应用因验证错误而停止。
要测试您的form.errors
,您可能希望直接调用表单ValidationError
而不是clean
。
答案 1 :(得分: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