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

重写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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:24:36