DRF中'Request'对象无'pop'属性,关联User创建Post失败
问题分析与解决方案
首先看你的报错核心:AttributeError: 'Request' object has no attribute 'pop',这是因为你重写create方法时参数写错了——ModelViewSet的create方法默认第一个参数是request,而不是validated_data,你把参数名搞混了,导致代码里的validated_data其实是请求对象,自然没有pop方法。
除此之外,你的序列化器逻辑也有问题:PostSerializer里直接用UserSerializer序列化author字段,会导致创建Post时要求前端传入完整用户信息,但我们的需求是自动使用当前登录用户作为作者,完全不需要前端传递这个字段。
下面是具体的修正步骤:
1. 调整序列化器(serializers.py)
把author字段设为只读,这样创建时不需要前端传值,但返回数据时依然能显示完整的用户信息:
class PostSerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name="api:posts-detail") author = UserSerializer(read_only=True) # 添加read_only=True标记 class Meta: model = models.Post fields = ['url', 'id', 'author', 'title', 'content']
2. 修正ViewSet的创建逻辑(views.py)
DRF的ModelViewSet已经封装了完整的创建流程,我们不需要重写整个create方法,只需要重写perform_create来注入当前登录用户即可,这是更符合DRF最佳实践的写法:
class PostViewSet(viewsets.ModelViewSet): serializer_class = serializers.PostSerializer # 保留你已有的get_queryset、permission_classes_by_action、get_permissions等代码 # 替换原来错误的create方法,用perform_create注入用户 def perform_create(self, serializer): # 保存时自动传入当前登录用户作为author serializer.save(author=self.request.user)
为什么之前的代码会失败?
- 参数错误:你给
create方法写了validated_data参数,但DRF的create方法签名是(self, request, *args, **kwargs),导致你操作的validated_data其实是请求对象,调用pop自然报错。 - 序列化器逻辑错误:
author字段未设为只读,导致创建时要求前端传入用户信息,违背了“自动使用当前登录用户”的需求。
现在按照上述修改,前端只需要传递title和content就能创建Post,author会自动关联当前登录用户,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Carlos
相关产品推荐
相关产品推荐

