Как тестировать поля модели Django

Я хочу сделать модульные тесты для полей модели Django:

  class Animal(models.Model):
    name = models.CharField(unique=True, max_length=30, blank=False, null=False)
    class Meta:
        managed = True
        db_table = 'animal'
        ordering = ['name']

Моя тестовая установка выглядит следующим образом:

class TestAnimalModel(TestCase):
    def setUp(self):
        self.animal = Animal.objects.create(name = 'TestAnimal')
        self.animal2 = Animal.objects.create(name = 123)
        self.animal3 = Animal.objects.create(name = 'TestAnimalWithTooManyCharacters')

animal2 и animal3 создаются, хотя не должны, потому что animal2.name - int, а animal3.name содержит более 30 символов.
Как проверить, что поле name имеет правильные значения?
Нормально ли, что объект создается, даже если его значения не соответствуют Model?

они не должны, потому что animal2.name это int

А CharField вызовет str(…) на том, что передано в качестве значения. Иногда это может иметь непредвиденные побочные эффекты. Но поля Django разработаны так, чтобы принимать различные значения. Например, для DateField оно также принимает дату, отформатированную как YYYY-MM-DD. Мы можем увидеть это в реализации CharField [GitHub]:

class CharField(Field):
    # …

    def to_python(self, value):
        """Return a string."""
        if value not in self.empty_values:
            value = str(value)
            if self.strip:
                value = value.strip()
        if value in self.empty_values:
            return self.empty_value
        return value

animal3.name имеет более 30 символов.

Если я запускаю это с MySQL, я получаю:

В зависимости от используемой базы данных, это может быть принято (не принято). SQLite, например, не принудительно ограничивает длину. Действительно, как сказано в FAQ от SQLite::

(9) Каков максимальный размер VARCHAR в SQLite?

.

SQLite не устанавливает длину переменной VARCHAR. Вы можете объявить VARCHAR(10), и SQLite будет рад хранить там строку из 500 миллионов символов. При этом все 500 миллионов символов останутся нетронутыми. Ваше содержимое никогда не будет усечено. SQLite понимает тип столбца "VARCHAR(N)" как тот же, что и "TEXT", независимо от значения N.

Поэтому SQLite не будет проверять его.

Вы можете позволить валидаторам Django выполнить валидацию перед сохранением в базе данных, например, с помощью:

animal = Animal(name='TestAnimalWithTooManyCharacters')
animal.full_clean()
animal.save()

Это позволит запустить валидаторы Django и вызвать исключения, если данные не являются действительными:

>>> animal = Animal(name='TestAnimalWithTooManyCharacters')
>>> animal.full_clean()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/django/env/lib/python3.8/site-packages/django/db/models/base.py", line 1238, in full_clean
    raise ValidationError(errors)
django.core.exceptions.ValidationError: {'name': ['Ensure this value has at most 30 characters (it has 31).']}

А Django ModelForm также проверит это и отклонит данные, переданные в форму, если строка слишком длинная.

Вернуться на верх