Где прописать валидацию в django?

Как лучше всего писать валидацию в проекте django? Что лучше - писать валидацию в сериализаторе или в моделях?

Я пробовал оба варианта написания валидации, но все равно не могу выбрать, где лучше написать валидацию.

Если у вас есть опыт работы в реальном проекте, то также поделитесь, где вы писали эту валидацию.

Валидация в основном относится к моделям. Действительно, модели сосредоточены на хранении данных, получении данных и проверке их достоверности.

А ModelSerializer для модели будет копировать эти валидаторы для моделей, которые она автоматически генерирует на основе этой модели. Так что если у вас есть поле с именем foo и ModelSerializer с fields = ['foo'], оно будет вызывать эти валидаторы.

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

Сериализаторы работают с запросом, в то время как модели должны быть не зависящими от запроса, поэтому проверка, которая зависит от самого запроса, должна проводиться в сериализаторе.

будьте осторожны. Вы действительно задаете вопрос о священной войне.

Django Models Fields / before-save-validation для проверки на уникальность и т.д.

Здесь вы имеете валидацию, которая не привязана строго к вашему юзер-кейсу. Мы размещаем такую проверку на уровне настроек, на уровне полей модели.

Например, правила пароля. Это не относится к пользователям. Это больше соображения безопасности для всех.

# settings.py
AUTH_PASSWORD_VALIDATORS = [
    {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}
]

Поля моделей Django / Поля формы / Поля сериализатора.

Здесь у вас есть валидация, которая не имеет строгого отношения к вашему пользовательскому случаю.

Например, поле "дата рождения". Для некоторых случаев вы хотите, чтобы в проекте везде присутствовал возраст > 18 лет на текущий момент времени. Это не совсем usecase, но уже некоторое правило валидации, согласованное с целями проекта.

class MyModel(models.Model):
    birthday = models.DateField(validators=[MinAgeValidator()])

Проверка уровня обслуживания.

Согласно Clean Architecture, проверка бизнес-целей должна применяться после обычной проверки. Это может быть метод form._post_clean или отдельный метод/функция где-то в конвейере данных. Это может быть реализовано как MixIn для формы/сериализатора.

class BusinessGoalValidationMixIn:

   def _post_clean(self, *args, **kwargs):
       response = super()._post_clean(*args, **kwargs)
       instance = form.save(commit=False)
       validate_something_in(instance)
       return response

Идея заключается в том, чтобы быть гибким в коде. Если вы видите, что вам нужно много раз повторять валидатор в сериализаторах, возможно, его можно перенести на слой модели, если вы используете одно и то же в каждом классе модели - возможно, это поле можно перенести в AbstractParentModelClass. Если правила строги всегда - возможно, это должна быть константа, определяемая в настройках/настройках приложения.

Но еще раз. Это мои субъективные предложения, и у нас нет никакого стандарта "где должны быть размещены валидаторы".

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