Django博客API获取文章时出现AttributeError: Post无comments属性
问题解决方法
错误原因
你在Post序列化器中定义了comments字段,但Post模型本身并没有这个属性。因为Comment模型通过外键post关联到Post,Django默认生成的反向关联名称是comment_set,而非comments,所以序列化器找不到对应属性触发报错。
解决方案(两种可选)
方案1:修改模型,自定义反向关联名称
在Comment模型的外键字段中添加related_name='comments',让Django直接将反向关联命名为comments,匹配序列化器的字段名:
修改models.py中的Comment类:
class Comment(TimeStamp): user = models.ForeignKey(User,on_delete=models.CASCADE) content = models.TextField(_("comments")) likes = models.IntegerField(_("likes"),default=0) # 添加related_name指定反向关联名称 post = models.ForeignKey(Post,on_delete=models.CASCADE, related_name='comments') def __str__(self): return self.content
同时,因为创建Post时不需要传入评论数据,给序列化器的comments字段加上read_only=True,避免创建接口出现验证错误:
修改serializers.py中的Post序列化器:
class Post(serializers.ModelSerializer): author = UserSr() # 添加read_only=True标记为只读字段 comments = Comment(many=True, read_only=True) class Meta: model = models.Post exclude = ['created_at','updated_at']
方案2:不修改模型,调整序列化器字段
如果不想改动模型,直接在序列化器中指定Django默认的反向关联名称:
修改serializers.py中的Post序列化器:
class Post(serializers.ModelSerializer): author = UserSr() # 用source指定默认的反向关联名comment_set comments = Comment(many=True, read_only=True, source='comment_set') class Meta: model = models.Post exclude = ['created_at','updated_at']
额外优化:避免N+1查询问题
在views.py的postGet视图中,预加载评论数据,提升接口性能:
@api_view(['GET']) def postGet(request): # 预加载关联的评论,减少数据库查询次数 posts = models.Post.objects.all().prefetch_related('comments') serializer = serializers.Post(posts,many=True) return Response(serializer.data, status=status.HTTP_200_OK)
(如果用方案2,这里要改为prefetch_related('comment_set'))
内容的提问来源于stack exchange,提问作者Maxon Sagnim
相关产品推荐
相关产品推荐

