自定义字段验证错误不显示字段名称

时间:2019-05-08 07:38:33

标签: python django django-rest-framework

我想实现一个更改密码端点, 我有这种看法:

 def update(self, request):
    user_data = {}
    classname = __class__.__name__
    function = 'update'
    try:
        user = request.user
        current = request.data['current']
        password = request.data['password']
        confirm = request.data['confirm']
        serializer = serializers.ChangePasswordSerializer(user, data=request.data)
        if serializer.is_valid():
            serializer.save(updated_by=request.user.username, updated_date=timezone.now())
            logger(request, msg=_("Added Successfully"), level="normal", classname=classname,
                   function=function,
                   user_data=user_data, status=status.HTTP_205_RESET_CONTENT)
            return Response({"message": _("Added Successfully")}, status=status.HTTP_205_RESET_CONTENT)
        logger(request, msg=serializer.errors, level="error", classname=classname, function=function,
               user_data=user_data, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
        return Response({'errors': serializer.errors}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)

    except Exception as ValidationError:
        return Response({"errors": _("Current password is not correct")}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)

    except Exception as e:
        elogger(msg=e.args)
        return Response({"message": _("status500")}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

这是我的序列化器:

 class ChangePasswordSerializer(DynamicFieldsModelSerializer):
     current = serializers.CharField()
     confirm = serializers.CharField()

    def validate(self, data):
        if data['current'] == data['password']:
            raise serializers.ValidationError("Password and Current password should not be the same")
        if data['confirm'] != data['password']:
            raise serializers.ValidationError("Password and Confirm password did not match")
        return data

    class Meta:
        model = models.User
        fields = ('password', 'current', 'confirm')
        validators = []

    def update(self, instance, validated_data):
        if not instance.check_password(validated_data.get('current')):
            raise serializers.ValidationError("Current password is not correct")
        else:
            instance.set_password(validated_data['password'])
            instance.save()
        return instance

我的第一个问题是我收到此验证错误:

{
   "errors": {
      "non_field_errors": [
         "Password and Current password should not be the same"
      ]
   }
}

我想使用字段名而不是“ non_field_errors”,我也想将我的检查密码功能放在validate函数中,但是我不知道如何

2 个答案:

答案 0 :(得分:1)

如果您通过 validate() 方法提出验证错误,请使用 dict 作为错误消息,< / p>

msg = {"field_name_1": "Password and Confirm password did not match"}
raise serializers.ValidationError(msg)

代码段

# serializer.py
class ChangePasswordSerializer(DynamicFieldsModelSerializer):
    foo = serializers.CharField()
    bar = serializers.IntegerField()

    # your code

    def validate(self, data):
        data = super().validate(data)
        errors = []
        if data['current'] == data['password']:
            msg_1 = {"field_name_1": "Password and Current password should not be the same"}
            errors.append(msg_1)

        if data['confirm'] != data['password']:
            msg_2 = {"field_name_2": "Password and Confirm password did not match"}
            errors.append(msg_2)
        if errors:
            raise serializers.ValidationError({"errors": errors})
        return data

答案 1 :(得分:1)

要获取字段验证错误,您必须从validate_fieldname函数引发错误,然后再次验证确认密码。

class ChangePasswordSerializer(DynamicFieldsModelSerializer):
    current = serializers.CharField()
    confirm = serializers.CharField()

    def validate_current(self, value):
        if value == self.initial_data['password']:
            raise serializers.ValidationError("Password and Current password should not be the same")
        return value

    def validate_confirm(self, value):
        if value != self.initial_data['password']:
            raise serializers.ValidationError("Password and Confirm password did not match")
        return value

    class Meta:
        model = models.User
        fields = ('password', 'current', 'confirm')
        validators = []

    def update(self, instance, validated_data):
        if not instance.check_password(validated_data.get('current')):
            raise serializers.ValidationError("Current password is not correct")
        else:
            instance.set_password(validated_data['password'])
            instance.save()
        return instance