2017-08-03 1 views
1

Je suis nouveau à Django en général alors s'il vous plaît ne me juge pas sévèrement.Comment normaliser la valeur du champ email dans Django REST Serializer?

J'ai un modèle utilisateur personnalisé et j'utilise DRF pour la création de profil utilisateur. Je normalise l'email dans le create_user (méthode du BaseUserManager). Je ne peux pas trouver le moyen de normaliser la valeur d'un champ email dans l'API Serializer. En fait, si je passe un e-mail qui existe déjà dans la base de données, mais seulement avec des lettres majuscules dans le domaine, il passera par la validation du sérialiseur, mais il frappera une erreur d'intégrité après:

duplicate key value violates unique constraint "accounts_user_email_key" DETAIL: Key (email)=([email protected]) already exists.

ici est une version abrégée de mon UserManager méthode:

class UserManager(BaseUserManager): 

    def create_user(self, email, first_name, last_name, password): 
     #some validation logic 
     #... 
     user = self.model(
      email=self.normalize_email(email), 
      first_name=first_name, 
      last_name=last_name 
     ) 
     user.set_password(password) 
     user.save() 
     return user 

    #other stuff... 

Voici une sérialiseur lui-même:

class UserSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = models.User 
     fields = ('email', 'first_name', 'last_name', 'password') 
     extra_kwargs = {k: {'write_only': True} for k in fields} 

    #some password validation... 

    def create(self, validated_data): 
     user = models.User.objects.create_user(
      email=validated_data['email'], 
      first_name=validated_data['first_name'], 
      last_name=validated_data['last_name'], 
      password=validated_data['password'] 
     ) 
     return user 

Voici la vue:

class UserCreate(generics.CreateAPIView): 
    serializer_class = serializers.UserSerializer 

Répondre

1

Vous pouvez utiliser field-level-validation dans sérialiseur:

class UserSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = models.User 
     fields = ('email', 'first_name', 'last_name', 'password') 
     extra_kwargs = {k: {'write_only': True} for k in fields} 

    def validate_email(self, value): 
     norm_email = value.lower() 
     if models.User.objects.fiter(email=norm_email).exists(): 
      raise serializers.ValidationError("Not unique email") 
     return norm_email 
+0

Salut. Merci pour la réponse. Je sais ce que vous voulez dire par cette validation, bien que je doive normaliser la valeur du champ email (de [email protected] à [email protected]) afin de valider. Dans le cas contraire, elle passe toujours par une validation unique si je transmets un courrier électronique qui existe déjà mais uniquement avec un domaine en majuscule. Comment puis-je accéder à la valeur du champ e-mail et peut-être la convertir en minuscules avant la validation et l'enregistrement dans le modèle utilisateur? – igsm

+0

J'ai ajouté votre logique au validateur, essayez-le. Vous pouvez changer le 'value.lower()' à votre méthode normalize_email. –

+0

Très bien! Merci beaucoup pour votre expérience! Cela fonctionne;) Mais en général, est-ce une pratique normale de faire cette tâche dans le Serializer ou cela peut-il être fait aussi dans la vue? – igsm