валидация структуры отдыха Django ведет себя аналогично валидации Django ModelForm
; он принимает аргументы из ваших полей моделей и соответственно проверяет.
Например, мы возьмем простой класс модель и сериализатор, который имеет поле с ограничением уникальности.
class CustomerReportRecord(models.Model):
time_raised = models.DateTimeField(default=timezone.now, editable=False)
reference = models.CharField(unique=True, max_length=20)
class CustomerReportSerializer(serializers.ModelSerializer):
class Meta:
model = CustomerReportRecord
и когда мы открываем оболочку Django, мы видим, что валидатор был применен к сериализатору (обратите внимание на max_length
и список validators
)
>>> from project.example.serializers import CustomerReportSerializer
>>> serializer = CustomerReportSerializer()
>>> print(repr(serializer))
CustomerReportSerializer():
id = IntegerField(label='ID', read_only=True)
time_raised = DateTimeField(read_only=True)
reference = CharField(max_length=20, validators=[<UniqueValidator(queryset=CustomerReportRecord.objects.all())>])
Печать repr
экземпляра сериализатора покажет вам, какие именно правила проверки он применяет. Для экземпляра модели не вызывается никаких дополнительных скрытых действий проверки.
Когда дело доходит до методов .clean
и .full_clean
, это просто еще один способ проверки введенных пользователем данных - нормализация их до согласованного формата. Они выполняются в формах Django, когда вы вызываете метод .is_valid()
в форме , а не в сериализаторе структуры остальных.
Вернемся к валидаторам REST framework. Давайте рассмотрим метод Serializer.to_internal_value
.
def to_internal_value(self, data):
"""
Dict of native values <- Dict of primitive datatypes.
"""
if not isinstance(data, dict):
message = self.error_messages['invalid'].format(
datatype=type(data).__name__
)
raise ValidationError({
api_settings.NON_FIELD_ERRORS_KEY: [message]
})
ret = OrderedDict()
errors = OrderedDict()
fields = self._writable_fields
for field in fields:
validate_method = getattr(self, 'validate_' + field.field_name, None)
primitive_value = field.get_value(data)
try:
validated_value = field.run_validation(primitive_value)
if validate_method is not None:
validated_value = validate_method(validated_value)
except ValidationError as exc:
errors[field.field_name] = exc.detail
except DjangoValidationError as exc:
errors[field.field_name] = list(exc.messages)
except SkipField:
pass
else:
set_value(ret, field.source_attrs, validated_value)
if errors:
raise ValidationError(errors)
return ret
Здесь мы видим, что сериализатор вызывает метод field.run_validation
, который использует валидаторы поля модели и выдает DjangoValidationError
, если проверка не удалась. Если это удастся, он продолжит запускать любые дополнительные валидаторы, такие как валидаторы, специфичные для полей сериализатора (.validate_<field_name>
).
Подробнее о проверке и о том, как она работает в Django & DRF, читайте здесь:
- Проверка поля формы Django 2.1
- Валидаторы - документы DRF
- Проверка сериализатора - документы DRF
- Правильный способ проверки моделей Django
- Код сериализатора DRF
Надеюсь, это поможет понять, как валидация работает в DRF, хотя бы немного
РЕДАКТИРОВАТЬ: Пока ваша область, в которой вы храните электронную почту, определена как EmailField
в ваших моделях, тогда DRF будет проверять электронную почту. Подробнее об этом можно узнать здесь