AssertionError: ValidationError не вызывается full_clean - PullRequest
0 голосов
/ 30 января 2020

В следующей форме я объявил clean() метод, который оценивает следующее условие:

Перед expiration_date стоит перед created_date?

Если это условие истинно, я хочу вызвать 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()

Ответы [ 2 ]

1 голос
/ 30 января 2020

Хотя ответ @Marcell действителен, я не думаю, что это является причиной поведения, которое вы испытываете.

Насколько я знаю, при вызове full_clean на ModelForm также вызывается метод clean, но ValidationErrors перехватывается внутри, и ошибка добавляется к form.errors. Таким образом, ваш тест не может увидеть эту ошибку. Это то, что вы сейчас видите в своем тесте. ИМХО, это поведение имеет смысл, поскольку вы, вероятно, не хотите, чтобы ваше приложение останавливалось на ошибке проверки.

Чтобы проверить ValidationError, вы можете вызвать метод clean напрямую, вместо full_clean.

0 голосов
/ 30 января 2020

Вам необходимо вернуть очищенные данные

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
...