属性错误:“元组”对象没有属性“值”

时间:2020-10-06 18:05:25

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

我有一个基本的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
        )

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

3 个答案:

答案 0 :(得分:0)

我不确定,但是好像serializers.py文件一样,您正在创建一个从dir()类继承的类。您有说serializers.Serializer的代码,这似乎与父类fields = ("password", "token", "uidb64",)中的一个字段发生了冲突。因此,一种解决方法是将serializers.Serializer变量重命名为field之类。

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

答案 1 :(得分:-1)

fields 应该在 Meta 类之内

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

答案 2 :(得分:-1)

您的序列化器需要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)