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

Django自定义用户模型下注册返回成功但用户未入库、登录报凭证无效问题

问题根因与修复方案

核心触发点

注册接口仅完成参数校验,未执行实际的数据库写入动作。
当前UserRegistrationAPIView的post方法逻辑中,Serializer校验通过后直接返回了校验后的请求数据,完全没有调用serializer.save()方法,因此Serializer内部定义的create逻辑从未被触发,用户对象根本没有被写入数据库。这也是为什么接口返回200状态码、但Django Shell查询不到新用户、登录接口始终验证失败的根本原因。

具体修复步骤

  • 补全注册接口的落库逻辑
    修正注册视图的post方法,校验通过后显式调用save动作:
    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid(raise_exception=True):
            user = serializer.save()  # 触发Serializer的create方法,完成用户入库
            # 仅返回公开字段,避免泄露敏感信息
            return Response(
                {"username": user.username, "email": user.email},
                status=status.HTTP_200_OK
            )
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
  • 修正用户管理器的参数隐患
    当前UserManager.create_user方法的密码参数默认值为password=False,存在安全风险:若调用时未传入密码,会将布尔值False传入set_password方法,生成非法的密码哈希。建议调整为和Django官方实现一致的password=None默认值。
  • 清理冗余的模型导入
    Serializer文件顶部同时导入了Django内置的User模型、自定义的backend.models.User,还通过get_user_model()定义了全局user变量,多套用户模型引用极易在后续开发中引发指向错误,建议删除未使用的内置User导入,统一使用自定义的用户模型。
  • 调整临时校验字段的处理逻辑
    password_2是仅用于二次密码校验的临时字段,不属于用户模型的固有字段,建议在create方法开头将其从validated_data中弹出,避免后续触发数据库字段不存在的报错:
    def create(self, validated_data):
        validated_data.pop('password_2', None)
        user = User(
            email=validated_data['email'],
            username=validated_data['username']
        )
        user.set_password(validated_data['password'])
        user.save()
        return user
    
  • 验证登录逻辑兼容性
    确保入库的用户is_active字段为默认的True,否则Django的authenticate方法会主动返回None,触发「Unable to log in with provided credentials.」的报错。当前模型的默认值配置已经满足要求,无额外调整必要。

内容的提问来源于stack exchange,提问作者dazai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 02:36:04