DRF登录视图自定义用户Serializer返回数据时validate方法异常求助
问题根源
- 触发新建账号逻辑的核心原因:你使用
UserLoginSerializer(data=request.data)初始化序列化器时未绑定已存在的用户实例,DRF ModelSerializer在无绑定实例的场景下运行校验逻辑,默认会触发创建用户的前置校验流程,加上你自定义的validate方法逻辑完全错误:self["username"]取到的是序列化器字段实例而非用户提交的值,还错误将password赋值为url字段实例,整体校验逻辑完全偏离预期。 - 冗余的重复校验:
TokenObtainPairView执行到finalize_response且response.data存在refresh字段时,说明用户身份已经校验通过,当前登录用户可直接从request.user获取,完全不需要再用请求参数二次校验用户身份。
正确实现方案
1. 修正序列化器
你只需要用序列化器输出用户公开信息,不需要保留密码字段,也不需要自定义校验逻辑:
# serializers.py class UserLoginSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = User fields = ("id", "url", "username")
2. 修正视图逻辑
直接绑定已登录的用户实例到序列化器,注意HyperlinkedModelSerializer需要传入request上下文才能生成正确的url字段:
# views.py class CookieTokenObtainPairView(TokenObtainPairView): def finalize_response(self, request, response, *args, **kwargs): # 先执行父类逻辑拿到基础响应 response = super().finalize_response(request, response, *args, **kwargs) if response.data.get("refresh"): # 直接用已经校验通过的当前用户实例序列化,不需要二次校验 user_serializer = UserLoginSerializer( instance=request.user, context={"request": request} ) response.data["user"] = user_serializer.data # 你原有设置cookie的逻辑保留在此处即可 return response
内容的提问来源于stack exchange,提问作者Nyll
相关产品推荐
相关产品推荐

