重写Django rest_auth LoginView时遇KeyError: 'user'问题求助
解决Django Rest Auth自定义LoginSerializer触发KeyError('user')的问题
这个问题我之前也遇到过,核心原因是rest_auth的LoginView依赖序列化器的validated_data里必须包含user键,而你的自定义序列化器可能在验证逻辑中没有正确返回这个键值对,尤其是自定义User模型(继承AbstractBaseUser)的场景下,容易忽略这个细节。
下面是具体的排查和解决步骤:
1. 检查自定义LoginSerializer的validate方法
这是最常见的问题点:你的序列化器在验证通过后,必须把认证成功的用户对象放到返回的字典中,确保validated_data里存在user键。
举个正确的示例(假设你用邮箱作为登录字段):
from rest_auth.serializers import LoginSerializer as BaseLoginSerializer from django.contrib.auth import authenticate from rest_framework import serializers class CustomLoginSerializer(BaseLoginSerializer): # 替换默认的username字段为email(如果你的用户模型用邮箱登录) email = serializers.EmailField(required=True) password = serializers.CharField(style={'input_type': 'password'}) def validate(self, attrs): email = attrs.get('email') password = attrs.get('password') request = self.context.get('request') # 注意:如果你的用户模型USERNAME_FIELD是email,这里用username=email也能正常认证 # 或者根据你的认证后端调整参数 user = authenticate(request=request, username=email, password=password) if not user: raise serializers.ValidationError("邮箱或密码错误") if not user.is_active: raise serializers.ValidationError("账号已被禁用") # 关键步骤:将用户对象存入attrs,确保返回的字典包含'user'键 attrs['user'] = user return attrs
如果是完全自定义的序列化器(不继承BaseLoginSerializer),也要保证validate方法最终返回的字典里有user键,因为LoginView会直接从serializer.validated_data['user']获取用户对象。
2. 确认自定义User模型的配置正确性
因为你的User继承自AbstractBaseUser,必须确保以下配置正确:
- 在
settings.py中指定自定义用户模型:AUTH_USER_MODEL = '你的应用名.你的User模型类名' - 在User模型中正确设置
USERNAME_FIELD(比如用邮箱登录的话):from django.contrib.auth.models import AbstractBaseUser, BaseUserManager class CustomUserManager(BaseUserManager): # 实现自定义的create_user和create_superuser方法 class CustomUser(AbstractBaseUser): email = models.EmailField(unique=True) # 其他自定义字段... USERNAME_FIELD = 'email' # 指定登录用的字段 REQUIRED_FIELDS = [] # 根据你的需求设置 objects = CustomUserManager() - 确保认证后端能正确识别你的用户模型,默认的
ModelBackend只要USERNAME_FIELD设置正确就能正常工作,不需要额外自定义。
3. 验证REST_AUTH_SERIALIZERS配置
检查settings.py中的配置是否正确指向你的自定义序列化器:
REST_AUTH_SERIALIZERS = { 'LOGIN_SERIALIZER': '你的应用名.serializers.CustomLoginSerializer', }
最后排查点
如果以上步骤都没问题,还可以:
- 打印
serializer.validated_data的内容,确认是否真的没有user键; - 检查
authenticate方法是否返回了有效的用户对象,有时候自定义用户模型的密码哈希逻辑错误会导致认证失败,返回None。
内容的提问来源于stack exchange,提问作者Babak Abadkheir
相关产品推荐
相关产品推荐

