1

Ceci est mon UserSerializer (j'utilise par défaut Django modèle User):Personnalisation ModelSerializer message d'erreur est ignorée

class UserSerializer(SetCustomErrorMessagesMixin, serializers.ModelSerializer): 

    def __init__(self, *args, **kwargs): 
      super(UserSerializer, self).__init__(*args, **kwargs) # call the super() 
      for field in self.fields: # iterate over the serializer fields 
       self.fields[field].error_messages['required'] = 'Enter a valid %s.'%field 
       self.fields[field].error_messages['null'] = 'Enter a valid %s.'%field 

       # class CharField(Field) errors 
       self.fields[field].error_messages['blank'] = 'Enter a valid %s.'%field 
       self.fields[field].error_messages['max_length'] = '%s cannot have more than {max_length} characters.'%field 
       self.fields[field].error_messages['min_length'] = '%s cannot have less than {min_length} characters.'%field 

    class Meta: 
     model = User 
     fields = ('username', 'password', 'email',) 

Le problème est, lorsqu'un utilisateur entre un nom d'utilisateur qui est trop long, l'erreur le message est

"Username is too long." 

D'où provient ce message d'erreur? J'ai écrasé le message d'erreur "max_length" dans le code ci-dessus, mais il ne le montre pas. Lorsque je supprime cette ligne de mon UserSerialzer:

self.fields[field].error_messages['max_length'] = '%s cannot have more than {max_length} characters.'%field 

le message d'erreur est:

"Ensure this field has no more than 30 characters." 

ce qui est logique beause il vient du code source CharField DRF ici: https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/fields.py

Mais où est "Nom d'utilisateur est trop long." venant de et comment cela se fait, il ne dit pas "Nom d'utilisateur ne peut pas avoir plus de {max_length} caractères." au lieu?

+0

D'où 'field' vient-il dans votre' __init__'? – Ivan

+0

@Ivan Désolé, lors du copier-coller de mon code, j'ai accidentellement supprimé cette ligne: "for field in self.fields:". J'ai édité mon post et ajouté la ligne maintenant. Cela a-t-il plus de sens? – user2719875

+0

Quelles versions de Django et DRF utilisez-vous? – Ivan

Répondre

1

Le problème semble être que DRF ajoute des validateurs pour les champs pendant leur construction et copie les messages d'erreur à partir des classes de champ.

Par exemple à partir rest_framework.fields.CharField.__init__:

if self.min_length is not None: 
    message = self.error_messages['min_length'].format(min_length=self.min_length) 
    self.validators.append(MinLengthValidator(self.min_length, message=message)) 

Ainsi, au moment où vous écrasez les messages, ils sont déjà utilisés dans les validateurs.

Je pense que vous pouvez simplement créer un module yourapp.fields où vous sous-classe DRF champs sérialiseur et passer outre à leurs default_error_messages, comme ceci:

from rest_framework import fields 

class CharField(fields.CharField): 

    default_error_messages = { 
     # Your messages 
    } 

Et puis juste passer le module vous importez des champs à partir.

Vous pouvez également remplacer __init__ s pour ajouter des noms de champ dans les messages.

+0

Je vois ce que vous voulez dire. Question rapide cependant: Juste pour clarifier, quand je surcharge les messages d'erreur avec: "self.fields [field] .error_messages ['max_length'] = '% s ne peut pas avoir plus de {max_length} caractères.'% Field ', quoi Je suis en train de contourner les validateurs de terrain DRF Serializer? Et quand j'utilise le code que vous avez posté, je remplace les valideurs de champ du modèle Django? – user2719875

+0

Non, je remplace les champs de sérialisation (j'ai même une importation dans mon code qui indique cela). En outre, si vous voulez des messages avec des noms de champs, vous pouvez également remplacer les '__init__'. – Ivan