J'ai un sérialiseur qui valide les champs en fonction des valeurs des autres champs. Dans la réponse d'erreur, j'aimerais afficher chaque erreur de champ comme une erreur de champ plutôt que de tout afficher sous "non_field_errors", ce qui se produirait si je levais une ValidationError dans la méthode validate au niveau de l'objet. Vous trouverez ci-dessous une illustration de ce que j'essaie de réaliser:
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's not valid in DRF
self._errors['field_val1'] = 'this field is not valid'
La réponse d'erreur souhaitée est:
{'field_val1': ['this field is not valid']}
Je l'ai compris, sur this page de la documentation dans la section "BaseSerializer", un exemple montre que ValidationError peut prendre un argument de dictionnaire lors de l'initialisation.
Si j'ai raise ValidationError({'field_val1': ['this field is not valid']})
j'obtiens la réponse JSON souhaitée.
Comme pour la réponse de @ Jkk.jonah, ceci soulève une ValidationError
, mais il réutilise le texte de l'exception d'origine sans qu'il soit nécessaire de réimplémenter les traductions:
try:
serializer.fields['field_val1'].fail('required')
except ValidationError as exc:
raise ValidationError({
'field_val1': exc.detail,
})
Par défaut (c'est-à-dire sur la classe rest_framework.fields.Field
), les clés disponibles sont les suivantes:
default_error_messages = {
'required': _('This field is required.'),
'null': _('This field may not be null.')
}
Les sous-classes peuvent y ajouter leurs propres messages d'erreur (et Serializer
est une sous-classe de Field
).
En passant, les nouveaux messages d’erreur seront automatiquement fusionnés avec les messages (Hérités) existants - ne seront pas remplacés comme prévu.
Si vous avez une logique qui s'applique à tous les champs, vous pouvez toujours obtenir le résultat souhaité en procédant comme suit:
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
Si vous utilisez des validateurs intégrés à DRF (qui sont en fait des validateurs principaux de Django), vous devez pré-traiter Django ValidationError provenant du validateur avec une fonction que get_error_detail
drf utilise à cette fin.
def _validate_min_value(self, data, key):
try:
MinValueValidator(Decimal('0.01'))(data.get(key))
except ValidationErrorDjango as exc:
raise ValidationError(
{key: get_error_detail(exc)}
)
Notez que ValidationErrorDjango est une ValidationError de Django.core.exceptions
, alors que ValidationError est une de rest_framework.exceptions