Django REST问题:认证用户未传入序列化器,提示字段必填
我之前也踩过这个坑!你遇到的serializer.save(posted_by=self.request.user)不生效、POST请求报错的问题,大概率是这几个常见原因导致的,咱们一步步排查解决:
1. 序列化器误将posted_by设为只读字段
这是最常见的原因!如果你的Serializer里把posted_by加入了read_only_fields列表,那即使你通过save()手动传递这个参数,序列化器也会直接忽略它——因为只读字段不会被纳入validated_data的处理流程。
比如错误示例:
# Serializers.py class YourModelSerializer(serializers.ModelSerializer): class Meta: model = YourModel fields = ['id', 'content', 'posted_by'] read_only_fields = ['posted_by'] # 这里加了就会导致传递无效
解决办法:直接把posted_by从read_only_fields里移除。因为你是通过后端代码传递该字段值,不需要前端提交,所以不用设置只读。
2. 重写了create方法但未处理posted_by参数
如果你自定义了序列化器的create方法,但没有把save()传递的posted_by合并到validated_data里,那数据库肯定会因为缺少必填字段报错。
错误示例:
def create(self, validated_data): # 完全没处理posted_by参数 return YourModel.objects.create(**validated_data)
正确写法:当你调用serializer.save(posted_by=self.request.user)时,这个参数会以关键字参数的形式传给create方法,你需要把它合并到validated_data后再调用父类方法:
def create(self, validated_data, **kwargs): # 把额外传递的posted_by加入validated_data validated_data['posted_by'] = kwargs['posted_by'] return super().create(validated_data)
或者更稳妥的方式:直接从序列化器上下文里取当前请求的用户(前提是视图初始化序列化器时传递了上下文):
def create(self, validated_data): validated_data['posted_by'] = self.context['request'].user return super().create(validated_data)
3. 视图初始化序列化器时未传递上下文(可选排查)
如果你是手动初始化序列化器(而非用DRF的通用视图),一定要记得传递包含request的上下文,否则序列化器里拿不到当前用户:
# views.py def your_view(request): serializer = YourModelSerializer( data=request.data, context={'request': request} # 必须传递这个上下文 ) if serializer.is_valid(): serializer.save(posted_by=request.user) return Response(serializer.data)
4. 快速验证小技巧
在视图的perform_create方法里打印validated_data,看看里面有没有posted_by字段:
def perform_create(self, serializer): print(serializer.validated_data) # 查看输出里是否包含posted_by serializer.save(posted_by=self.request.user)
如果输出里没有posted_by,基本可以锁定是序列化器的只读设置或者create方法的问题。
内容的提问来源于stack exchange,提问作者GRS

