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
相关产品推荐
相关产品推荐

