Django REST Framework中GET可识别request.user但POST请求报错咨询
问题解答
1. self.request.user的获取来源
Django的request.user是由AuthenticationMiddleware中间件处理赋值的:
- 每次请求进入服务端时,中间件会从请求携带的身份凭证(比如Cookie里存储的sessionid、认证token等)匹配对应的用户对象
- 身份验证通过就挂载为对应的
User实例,未验证通过则挂载为AnonymousUser匿名用户实例 - DRF框架会继承Django原生的这个逻辑,同时也会走自身配置的认证类规则处理身份,最终把验证后的用户对象挂载到
request.user上。
2. POST请求报错的原因与修复方案
你遇到的{"user":["This field is required."]}错误和身份识别无关:你已经配置了IsAuthenticated权限,能进入POST接口说明用户已经被正常识别,报错是序列化器的校验逻辑导致的。
错误原因
你使用的ListCreateAPIView在处理POST创建请求时,会调用NotesSerializer校验前端提交的参数。你的Notes模型中user字段是必填外键,你既没有让前端提交user参数,也没有在创建逻辑中自动注入当前登录用户,所以序列化器直接抛出必填字段校验错误。
GET请求正常是因为GET走的是列表查询逻辑,仅执行get_queryset过滤数据,不需要校验前端提交的创建参数。
修复方案
选择以下任意一种方案即可:
方案1:设置user字段为只读,创建时自动注入
首先修改NotesSerializer,将user字段设为只读,无需前端传参:
from rest_framework import serializers from api.models.notes import Notes class NotesSerializer(serializers.ModelSerializer): class Meta: model = Notes fields = '__all__' # 保留你原有fields配置不变,新增下面一行即可 read_only_fields = ('user',)
然后修改视图类,重写perform_create方法,创建笔记时自动注入当前登录用户:
class FilterNotes(generics.ListCreateAPIView): serializer_class = NotesSerializer permission_classes = (IsAuthenticated,) def get_queryset(self): return Notes.objects \ .filter(user=self.request.user.id) \ .order_by('-time') # 新增这个方法即可 def perform_create(self, serializer): serializer.save(user=self.request.user)
方案2:序列化器排除user字段
如果你完全不需要把user字段返回给前端,可以直接在序列化器的fields配置里去掉user字段,同样需要重写上述perform_create方法注入当前登录用户。
内容的提问来源于stack exchange,提问作者olga_it_proger
相关产品推荐
相关产品推荐

