You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:55:20