【问题标题】:Attribute Error: 'tuple' object has no attribute 'values'属性错误:“元组”对象没有属性“值”
【发布时间】:2021-01-21 15:59:07
【问题描述】:

我有一个基本的 API 来重置密码,但是,它似乎抛出了这个错误,尽管“值”完全没有出现在我的代码中:

views.py

class PasswordResetNewPasswordAPIView(GenericAPIView):
    serializer_class = SetNewPasswordSerializer

    def patch(self, request):
        user = request.data
        serializer = SetNewPasswordSerializer(data=user)
        serializer.is_valid(raise_exception=True)
        return Response({
            "message": "password reset"},
            status=status.HTTP_200_OK
        )

序列化器.py

class SetNewPasswordSerializer(serializers.Serializer):
    password = serializers.CharField(max_length=50, write_only =True)
    token = serializers.CharField(write_only =True)
    uidb64 = serializers.CharField(max_length = 255, write_only =True)

    fields = ("password", "token", "uidb64",)

    def validate(self, attrs):
        try:
            password = attrs.get("password", "")
            token = attrs.get("token", "")
            uidb64 = attrs.get("uidb64", "")
            print(uidb64)
            id = force_str(urlsafe_base64_decode(uidb64))
            print(id)
            user = Author.objects.get(id=id)
            if not PasswordResetTokenGenerator().check_token(user, token):
                raise AuthenticationFailed("Invalid Reset Parameter", 401)
            user.set_password(password)
            user.save()
            return user
        except Exception:
            raise AuthenticationFailed("Invalid Reset Parameter", 401)
        return super().validate(attrs)

urls.py

...
path('password-reset-setup/', PasswordResetNewPasswordAPIView.as_view(),name="password-reset-setup"),

可能的错误是什么?以及如何绕过它?

回溯是:

Traceback (most recent call last):
  File "/home/pratyush/Desktop/NewsSite/newsite/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/pratyush/Desktop/NewsSite/newsite/lib/python3.8/site-packages/django/core/handlers/base.py", line 202, in _get_response
    response = response.render()
  File "/home/pratyush/Desktop/NewsSite/newsite/lib/python3.8/site-packages/django/template/response.py", line 105, in render
    self.content = self.rendered_content
  File "/home/pratyush/Desktop/NewsSite/newsite/lib/python3.8/site-packages/rest_framework/response.py", line 70, in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
  File "/home/pratyush/Desktop/NewsSite/newsite/lib/python3.8/site-packages/rest_framework/renderers.py", line 724, in render
    context = self.get_context(data, accepted_media_type, renderer_context)
  File "/home/pratyush/Desktop/NewsSite/newsite/lib/python3.8/site-packages/rest_framework/renderers.py", line 657, in get_context
    raw_data_patch_form = self.get_raw_data_form(data, view, 'PATCH', request)
  File "/home/pratyush/Desktop/NewsSite/newsite/lib/python3.8/site-packages/rest_framework/renderers.py", line 563, in get_raw_data_form
    data = serializer.data.copy()
  File "/home/pratyush/Desktop/NewsSite/newsite/lib/python3.8/site-packages/rest_framework/serializers.py", line 548, in data
    ret = super().data
  File "/home/pratyush/Desktop/NewsSite/newsite/lib/python3.8/site-packages/rest_framework/serializers.py", line 250, in data
    self._data = self.get_initial()
  File "/home/pratyush/Desktop/NewsSite/newsite/lib/python3.8/site-packages/rest_framework/serializers.py", line 398, in get_initial
    for field in self.fields.values()

Exception Type: AttributeError at /authors/password-reset-setup/
Exception Value: 'tuple' object has no attribute 'values'

【问题讨论】:

    标签: python django django-rest-framework django-views django-rest-framework-jwt


    【解决方案1】:

    我不完全确定,但它似乎是 serializers.py 文件,您正在创建一个继承自 serializers.Serializer 类的类。你的代码写着fields = ("password", "token", "uidb64",),这似乎与父类serializers.Serializer 中的一个字段发生冲突。因此,一种解决方法是将field 变量重命名为my_field

    如果您打算覆盖该变量,那么它应该是一个列表,而不是一个元组。将其从fields = ("password", "token", "uidb64",) 更改为fields = ["password", "token", "uidb64"]

    【讨论】:

      【解决方案2】:

      fields 应该在 Meta 类中

      class SetNewPasswordSerializer(serializers.Serializer):
          # rest of your code
          class Meta:
              fields = ("password", "token", "uidb64",)

      【讨论】:

        【解决方案3】:

        您的序列化程序需要Meta 来声明模型字段。

        试试这个:

        class SetNewPasswordSerializer(serializers.Serializer):
            password = serializers.CharField(max_length=50, write_only =True)
            token = serializers.CharField(write_only =True)
            uidb64 = serializers.CharField(max_length = 255, write_only =True)
        
        
            class Meta: # you missed meta to declare your model fields
        
                fields = ("password", "token", "uidb64",)
        
            def validate(self, attrs):
                try:
                    password = attrs.get("password", "")
                    token = attrs.get("token", "")
                    uidb64 = attrs.get("uidb64", "")
                    print(uidb64)
                    id = force_str(urlsafe_base64_decode(uidb64))
                    print(id)
                    user = Author.objects.get(id=id)
                    if not PasswordResetTokenGenerator().check_token(user, token):
                        raise AuthenticationFailed("Invalid Reset Parameter", 401)
                    user.set_password(password)
                    user.save()
                    return user
                except Exception:
                    raise AuthenticationFailed("Invalid Reset Parameter", 401)
                return super().validate(attrs)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-06-26
          • 2014-05-14
          • 2016-04-07
          • 1970-01-01
          • 1970-01-01
          • 2018-05-21
          • 2021-03-20
          • 1970-01-01
          相关资源
          最近更新 更多