Django REST Framework报错:'ResetPasswordRequestSerializer'无'id'属性
解决密码重置API中的序列化器与User模型对象混淆问题
问题核心
你误将ResetPasswordRequestSerializer实例当成了User模型对象使用,导致调用user.id时触发AttributeError;后续令牌生成的错误也源于同样的原因——传入了错误的对象类型。
具体解决步骤
1. 修正序列化器逻辑,正确关联User模型对象
序列化器的作用是校验输入并查询对应的User实例,而非自身作为User对象存在。示例写法:
from rest_framework import serializers from django.contrib.auth.models import User class ResetPasswordRequestSerializer(serializers.Serializer): email = serializers.EmailField() def validate_email(self, value): # 通过邮箱查询User模型实例 try: user = User.objects.get(email=value) except User.DoesNotExist: raise serializers.ValidationError("该邮箱未注册") # 将User实例存入序列化器context,供视图调用 self.context["user"] = user return value
2. 在视图中正确获取User模型实例
视图里不能直接把序列化器实例赋值给user变量,要从序列化器的context中提取真正的User对象:
from rest_framework.views import APIView from rest_framework.response import Response from django.utils.http import urlsafe_base64_encode from django.contrib.auth.tokens import default_token_generator class ResetPasswordRequestAPI(APIView): def post(self, request): serializer = ResetPasswordRequestSerializer(data=request.data) serializer.is_valid(raise_exception=True) # 从context中取出User模型实例 user = serializer.context["user"] # 正常生成uidb64和令牌 uidb64 = urlsafe_base64_encode(str(user.id).encode()) token = default_token_generator.make_token(user) # 后续业务逻辑... return Response({"message": "重置链接已生成", "uidb64": uidb64, "token": token})
3. 排查User对象字段缺失问题
如果查询到的User实例看似缺少id等字段,大概率是以下原因:
- 查询User时误用了
values()/values_list(),返回的是字典/列表而非模型实例,需改用get()/filter().first()获取实例 - 自定义User模型未正确配置:未在
settings.py中设置AUTH_USER_MODEL,或自定义模型未继承AbstractUser/AbstractBaseUser并声明主键 - 混淆了序列化器字段与模型字段:模型实例本身必然包含
id(除非自定义了非默认主键),若序列化器未声明id字段,不代表模型实例缺失该属性
4. 令牌生成错误的解决
令牌生成时的AttributeError本质是传入了非User模型实例,只要确保传给default_token_generator.make_token()的是真正的User模型对象,即可解决该问题。
内容的提问来源于stack exchange,提问作者Sid
相关产品推荐
相关产品推荐

