queryset framework fields error create django django-rest-framework

fields - Mensajes de error personalizados en el serializador Django Rest Framework.



raise exception django rest framework (6)

DRF3.0 espera que definamos explícitamente los validadores para los campos si deseamos anular los validadores de modelo predeterminados. Esto se puede hacer pasando extra_kwargs y definiendo explícitamente los validadores para cualquier campo que parezca necesario. También puede especificar su propio validador personalizado que puede reutilizarse de nuevo para diferentes campos o incluso otros serializadores.

http://www.django-rest-framework.org/api-guide/serializers/#validation

http://www.django-rest-framework.org/api-guide/validators/#validation-in-rest-framework

# my_app/validators.py def validate_required(value): # whatever validation logic you need if value == '''' or value is None: raise serializers.ValidationError(''This field is required.'') # my_app/serializers.py class MyModelSerializer(serializers.ModelSerializer): class Meta: model = MyModel extra_kwargs = {"field1": {"validators": [validators.validate_required,]}}

El escenario es bastante sencillo:

Tengo un modelo con algunos campos que son requeridos. Digamos que uno de ellos es un TextField que no puede estar en blank . También tengo un ModelSerializer (Django Rest Framework) que representa ese modelo.

Cuando se usa una cadena vacía para establecer ese campo a través del serializador, el error devuelto proviene del propio modelo ( This field can''t be blank ).

Me gustaría anular los mensajes de error solo en el nivel de serializador, sin la necesidad de volver a especificar explícitamente cada campo en el serializador (que creo que está en contra del principio DRY), tener que escribir un método validate_ para cada campo y elevar mi propio ValidationError o tener que cambiar los mensajes de error en el nivel del Model (porque a veces el contexto del mensaje de error es importante para mi caso de uso y el mensaje de error debe darse en consecuencia).

En otras palabras, ¿hay una manera de anular los mensajes de error en el nivel de serializador tan fácil como es para un ModelForm :

class MyModelForm(ModelForm): class Meta: model = MyModel error_messages = {"field1": {"required": _("For some reason this is a custom error message overriding the model''s default")}}


En su serializador:

class UserSerializer(serializers.ModelSerializer): class Meta: model = User def __init__(self, *args, **kwargs): super(UserSerializer, self).__init__(*args, **kwargs) self.fields[''username''].error_messages[''required''] = u''My custom required msg''

Tenga en cuenta que algunos mensajes de error consisten en %s marcadores de posición como:

''invalid'': _("''%s'' value must be either True or False."),

para BooleanField .

Por lo tanto, debe revisar la parte default_error_messages en cada tipo de campo en el fields.py del DRF, para usarlo correctamente.


Otro enfoque para UniqueValidator (para usar con ModelSerializer):

def __init__(self, *args, **kwargs): super(UserSerializer, self).__init__(*args, **kwargs) # Find UniqueValidator and set custom message for validator in self.fields[''email''].validators: if isinstance(validator, validators.UniqueValidator): validator.message = _(''This email already exist on this site'')


Solo una nota, ya que jugué con esto por un tiempo, si estás usando algo como un campo de URL que solo agrega un URLValidator, no parece usar los mensajes de error, así que hice algo similar a la respuesta de @ Hugo:

class Meta: extra_kwargs = {"url_field": {"validators": [validators.URLValidator(message="My error message")]}}


unique error_messages de error_messages parecían ignorarse de forma unique , por lo que tuve que adoptar un enfoque diferente.

email = serializers.EmailField(validators=[ UniqueValidator( queryset=models.Client.objects.all(), message="My custom error", )] )

Es más simple (pero menos flexible, menos reutilizable) que @ gabriel-amram, pero mucho menos intrépido que @ mariodev.


EDIT: Veo que esta pregunta aún recibe algunas opiniones, por lo que es importante tener en cuenta que hay otro enfoque, mucho más claro que la respuesta original que publiqué aquí.

Puedes usar el atributo extra_kwargs de la clase Meta del serializador, así:

class UserSerializer(ModelSerializer): class Meta: model = User extra_kwargs = {"username": {"error_messages": {"required": "Give yourself a username"}}}

Respuesta original:

Usando la respuesta de @mariodev, creé una nueva clase en mi proyecto que hace eso:

from rest_framework.serializers import ModelSerializer, ModelSerializerOptions class CustomErrorMessagesModelSerializerOptions(ModelSerializerOptions): """ Meta class options for CustomErrorMessagesModelSerializerOptions """ def __init__(self, meta): super(CustomErrorMessagesModelSerializerOptions, self).__init__(meta) self.error_messages = getattr(meta, ''error_messages'', {}) class CustomErrorMessagesModelSerializer(ModelSerializer): _options_class = CustomErrorMessagesModelSerializerOptions def __init__(self, *args, **kwargs): super(CustomErrorMessagesModelSerializer, self).__init__(*args, **kwargs) # Run through all error messages provided in the Meta class and update for field_name, err_dict in self.opts.error_messages.iteritems(): self.fields[field_name].error_messages.update(err_dict)

El primero da la posibilidad de agregar un nuevo atributo de clase Meta al serializador como con el ModelForm . La segunda hereda de ModelSerializer y utiliza la técnica de @ mariodev para actualizar los mensajes de error.

Todo lo que queda por hacer, es simplemente heredarlo, y hacer algo así:

class UserSerializer(CustomErrorMessagesModelSerializer): class Meta: model = User error_messages = {"username": {"required": "Give yourself a username"}}