Где прописать валидацию в 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
. Если правила строги всегда - возможно, это должна быть константа, определяемая в настройках/настройках приложения.
Но еще раз. Это мои субъективные предложения, и у нас нет никакого стандарта "где должны быть размещены валидаторы".