django rest framework: установить ошибку на уровне поля из метода serialify validate()
У меня есть сериализатор, который проверяет поля на основе значений других полей. В ответе об ошибке я хотел бы показать каждую ошибку поля как полевую ошибку, а не показывать все под "non_field_errors", что и произойдет, если я буду поднимать ValidationError в методе проверки уровня объекта. Ниже приведен пример того, чего я пытаюсь достичь:
MySerializer(ModelSerializer):
...
def validate(self, data):
field_val1 = data['field_val1']
field_val2 = data['field_val2']
if not self._is_field_valid(field_val1, field_val2):
# The below line is how I would do what I want with Django
# Forms, however, it not valid in DRF
self._errors['field_val1'] = 'this field is not valid'
Требуемый ответ об ошибке:
{'field_val1': ['this field is not valid']}
Ответы
Ответ 1
Я понял это на этой странице документации в разделе "BaseSerializer", там пример, показывающий ValidationError, может принимать аргумент словаря при инициализации.
Если я raise ValidationError({'field_val1': ['this field is not valid']})
Я получаю ответ JSON, который я хочу.
Ответ 2
Подобно ответу @Jkk.jonah, это вызывает ValidationError
, но он повторно использует исходный текст исключения без необходимости повторной реализации переводов:
try:
serializer.fields['field_val1'].fail('required')
except ValidationError as exc:
raise ValidationError({
'field_val1': exc.detail,
})
По умолчанию (т.е. по классу rest_framework.fields.Field
) доступными ключами являются:
default_error_messages = {
'required': _('This field is required.'),
'null': _('This field may not be null.')
}
Подклассы могут добавлять там свои собственные сообщения об ошибках (и Serializer
- подкласс Field
).
BTW, новые сообщения об ошибках будут автоматически объединены с существующими (унаследованными) сообщениями - не будут переопределены, как можно было бы ожидать.
Ответ 3
Если у вас есть логика, применимая ко всем полям, вы можете получить желаемый результат, выполнив следующие действия:
def validate(self, data):
for key, value in data.items():
# checks if value is empty
if not value:
raise serializers.ValidationError({key: "This field should not be left empty."})
return data