【问题标题】:Django-Rest-Framework Serializer validate data return NoneDjango-Rest-Framework Serializer 验证数据返回无
【发布时间】:2021-04-01 20:58:02
【问题描述】:

我无法在我的 API 的 Serializer 的 validate() 函数中获取数据。我正在使用 django AbstractUser 模型

Django = "^3.1.3"
djangorestframework = "^3.12.2"

我的 serializers.py:

class ChangePasswordSerializer(serializers.Serializer):
    old_password = serializers.CharField(max_length=255, required=True)
    new_password = serializers.CharField(max_length=255, required=True, write_only=True)
    new_password_confirm = serializers.CharField(max_length=255, required=True, write_only=True)

    def validate_old_password(self, value):
        if not self.context['user'].check_password(value): # got data
            raise serializers.ValidationError("Incorrect Old Password") 
    
    def validate_new_password(self, value):
        try:
             # validate the password and catch the exception
            validators.validate_password(password=value) # got data

         # the exception raised here is different than serializers.ValidationError
        except exceptions.ValidationError as e:
            raise serializers.ValidationError(list(e)) 
    
    def validate_new_password_confirm(self, value):
        try:
             # validate the password and catch the exception
            validators.validate_password(password=value) # got data

         # the exception raised here is different than serializers.ValidationError
        except exceptions.ValidationError as e:
            raise serializers.ValidationError(list(e)) 
    
    def validate(self, data):
        if data['new_password'] != data['new_password_confirm']: # both return None
            raise serializers.ValidationError({'message': ["Your password and confirmation password do not match."]})
        
        return data

views.py:

class change_password(APIView):

    def post(self, request):
        received_json_data=request.data
        user = request.user
        serializer = ChangePasswordSerializer(data=received_json_data, context={'user': user})
        if serializer.is_valid():
            user.set_password(received_json_data['new_password']) # got new_password
            return JsonResponse({
                'message': 'Password changed.'
            }, status=200)
        else:
            return JsonResponse({'message':serializer.errors}, status=400)

问题在于 validate(self, data) 数据当前返回为 OrderedDict([('old_password', None), ('new_password', None), ('new_password_confirm', None)]) 所以它跳过了自定义验证,但在其他验证方法 validate_old_password validate_new_passwordvalidate_new_password_confirm打印出来

我很困惑为什么会这样

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    您始终必须在验证方法中返回值。

    而不是这个不返回值:

    def validate_old_password(self, value):
        if not self.context['user'].check_password(value): # got data
            raise serializers.ValidationError("Incorrect Old Password") 
    

    你必须这样写:

    def validate_old_password(self, value):
        if not self.context['user'].check_password(value): # got data
            raise serializers.ValidationError("Incorrect Old Password")
    
        return value 
    

    这也是validate方法没有收到数据的原因,因为各个字段的验证方法首先运行。

    【讨论】:

    • 哦,我明白了,如果缺少返回数据,前 3 个验证不会像 validate() 中那样通知错误需要返回,这很奇怪。文档也没有提及太多;-; django-rest-framework.org/api-guide/validators/#optional-fields。但是感谢您的回答,它有效(我会在允许时接受)
    • 提到了字段级验证章节here
    猜你喜欢
    • 2017-02-02
    • 1970-01-01
    • 2020-03-05
    • 2020-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    相关资源
    最近更新 更多