DRF返回关联模型字段时出现'QuerySet无user属性'报错的解决方法
报错原因
你遇到的'QuerySet' object has no attribute 'user'错误由以下几个问题共同导致:
- 视图中查询评论时调用了
.values(),返回的结果是纯字典组成的QuerySet,而非Comment模型实例。序列化器中自定义方法需要通过模型实例的外键关联访问user对象,字典类型没有.user属性,直接触发报错。 - 序列化多条评论数据时,未给序列化器传入
many=True参数,序列化器无法正确处理QuerySet类型的多对象输入。 - 额外的隐性问题:
- GET请求的参数应该从
request.query_params获取,你用request.data取值在标准GET请求下拿不到参数 - APIView的认证、权限类属性名拼写错误,正确写法是
authentication_classes和permission_classes(末尾带s),否则配置不会生效 - 序列化器中访问
self.context['request'],但你初始化序列化器时没有传入request上下文,后续会触发KeyError - 直接访问
comment.user.avi_pic.url没有做判空,用户未上传头像时会抛出属性错误
- GET请求的参数应该从
修复方案
第一步:修正视图代码
class CommentView(APIView): # 修正属性名拼写 authentication_classes = [authentication.TokenAuthentication] permission_classes = [permissions.IsAuthenticated] serializer_class = CommentSerializer # Get all comments from current post def get(self, request): # GET请求参数从query_params获取 post_id = request.query_params.get('id') post = Post.objects.get(id=post_id) # 去掉.values(),用select_related预加载关联user对象,减少数据库查询次数 comments = Comment.objects.filter(post=post).select_related('user') # 传入many=True适配多对象序列化,传入context保证序列化器能拿到request对象 serializer = CommentSerializer(comments, many=True, context={'request': request}) return Response(serializer.data, status=status.HTTP_200_OK)
第二步:优化序列化器(同时修复空值报错)
你当前写的SerializerMethodField可以简化,同时补充头像判空逻辑,避免用户无头像时接口报错:
class CommentSerializer(serializers.ModelSerializer): username = serializers.CharField(source='user.username', read_only=True) avi_pic = serializers.SerializerMethodField() class Meta: model = Comment fields = '__all__' def get_avi_pic(self, comment): request = self.context.get('request') # 判空:用户没上传头像时直接返回None,不强行取url if not comment.user.avi_pic or not request: return None return request.build_absolute_uri(comment.user.avi_pic.url)
改完之后接口就能正常返回评论关联的用户名、头像地址,不会再抛出属性错误。
内容的提问来源于stack exchange,提问作者jdez
相关产品推荐
相关产品推荐

