Serializer字段验证以及如何检查值是否存在?

问题描述 投票:0回答:2

我有2个模型,UserUserProfileUserProfile型号与OneToOneField型号同时具有User。在这里,我试图在一个请求中更新两个模型。

请求有效载荷:

{'email': ['[email protected]'], 'first_name': ['Nalin'], 'last_name': ['Dobhal'],}

我已经为两个模型创建了序列化器。

serializers.py

class UserAccountSerializer(serializers.ModelSerializer):

    id = serializers.IntegerField(required=False, read_only=True)
    mobile = serializers.IntegerField(read_only=True)
    email = serializers.EmailField(required=False, read_only=False)
    username = serializers.CharField(read_only=True)

    class Meta:
        model = User
        fields = ("id", "mobile", 'email', "username",)

class UserProfileSerializer(serializers.ModelSerializer):

    user = UserAccountSerializer(required=False, read_only=False)
    # other fields
    class Meta:
        model = UserProfile
        fields = ("user", # other fields)

    def update(self, instance, validated_data):
        # validated data doesn't have email here, that's why getting value from self.initial_data
        if self.initial_data.get("email"):

            instance.user.email = self.initial_data.get("email")
            instance.user.save()

        instance.save()
        return instance

views.py

class UserAccountSettingsAPI(generics.RetrieveUpdateAPIView):
    http_method_names = ["options", "get", "put", "patch"]
    permission_classes = (IsAuthenticated,)
    authentication_classes = (TokenAuthentication,)
    serializer_class = UserProfileSerializer

    def get(self, request, *args, **kwargs):
    # some processing

    def update(self, request, *args, **kwargs):
        profile = UserProfile.objects.select_related("user").get(user_id=request.user.id)
        serializer = self.get_serializer(profile, data=request.data)
        if serializer.is_valid(raise_exception=False):
            serializer.save()
        # some other processing only to set key value for context.
        return Response(context)

我想在更新用户的电子邮件之前进行一些验证。所以我的问题是在哪里进行验证?有没有更好的方法可以做到这一点?我试图在def validate_email(self, email):中添加UserAccountSerializer,但没有得到执行。因此,我想确保电子邮件不属于其他用户,并且如果电子邮件存在,我想向客户端发送一些自定义错误消息。我已删除了不必要的代码。

python django django-rest-framework django-serializer
2个回答
0
投票

尝试添加此代码

在视图中创建或更新

if User.objects.filter(email=self.request.data['email']).exists():
    return Response({"error": "This email id already exists."})

0
投票

我假设您希望email是唯一的。然后,您应该在用户模型的电子邮件字段中添加unique=True

class YourUserModel(AbstractUser):
    email = models.EmailField(unique=True)

在将电子邮件设为唯一字段之后,您的数据库将不允许添加其他具有相同电子邮件的条目,它将引发IntegrityError。您可以捕获此错误,并向用户返回更好的错误消息。像这样:

try:
    if serializer.is_valid(raise_exception=False):
        serializer.save()
except IntegrityError:
    return Response(data={'message':'that email is in use'}, status=HTTP_400_BAD_REQUEST)
© www.soinside.com 2019 - 2024. All rights reserved.