如何在Django REST Serializer中规范化电子邮件字段值?

时间:2017-08-03 20:00:18

标签: python django django-rest-framework django-serializer

我是Django的新手,所以请不要严厉地评价我。

我有自定义用户模型,我使用DRF创建用户个人资料。我将 create_user (BaseUserManager的方法)中的电子邮件规范化。我找不到如何规范API Serializer中电子邮件字段值的方法。基本上,如果我传递一个已经存在于数据库中的电子邮件,但只是在域中使用大写字母,它将通过序列化程序的验证,但是在它之后它会遇到完整性错误:

duplicate key value violates unique constraint "accounts_user_email_key" DETAIL: Key (email)=(email@example.com) already exists.

以下是 UserManager 方法的简化版本:

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...

这是序列化程序本身:

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

以下是视图

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

1 个答案:

答案 0 :(得分:1)

您可以在序列化程序中使用field-level-validation

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