Django ORM在列表视图中逐个查询Post对象是否正常?
Django Post列表查询出现额外
posts_post查询的问题 问题描述
我在获取所有Post对象(共4条)时,每个实体都触发了4次对posts_post表的额外查询,想知道针对根实体(Post)的单独查询是否属于正常行为?
模型定义
class Post(models.Model): profile = models.ForeignKey(Profile, related_name="posts", on_delete=CASCADE) project = models.ForeignKey(Project, related_name="posts", on_delete=CASCADE) body = models.TextField(verbose_name="Content", max_length=1300) liked_by = models.ManyToManyField(Profile, related_name="post_likes", blank=True) date_published = models.DateTimeField(auto_now_add=True, verbose_name="Date published") date_modified = models.DateTimeField(auto_now=True, verbose_name="Date modified") is_active = models.BooleanField(verbose_name="Active", default=True) tags = TaggableManager(blank=True, related_name="posts")
视图代码
class PostListAPIView(APIView): def get(self, request) -> Response: """Return a list of all posts.""" all_posts = ( Post.objects .select_related("profile__specialization", "project") .prefetch_related( "tags", Prefetch( "liked_by", queryset=Profile.objects.select_related("specialization").only( "id", "username", "first_name", "last_name", "photo", "specialization" ) ) ) .annotate( comments_count=Count("comments", distinct=True), likes_count=Count("liked_by", distinct=True) ) .defer("body") .order_by("-date_published") ) post_serializer = PostDetailDTOSerializer(all_posts, many=True) posts_serialized_data = post_serializer.data return Response( { "posts": posts_serialized_data, }, status=status.HTTP_200_OK )
查询情况
通过Django Debug Toolbar可见,针对4个Post对象,每个都产生了额外的SELECT * FROM posts_post WHERE id = ?查询,共出现4次这类额外查询。
分析与解决
这种根实体的重复查询不属于正常行为,大概率是查询集的字段加载策略和序列化器需求不匹配导致的,常见原因和解决方法如下:
检查序列化器是否访问了被延迟加载的字段
你在查询中使用了.defer("body"),如果PostDetailDTOSerializer中包含了body字段,每个Post对象在序列化时都会单独查询数据库获取body值,触发额外查询。
解决:如果不需要返回body,确保序列化器中不包含该字段;如果需要返回body,去掉查询中的.defer("body")。排查序列化器是否访问了Post模型的其他未加载字段
确认序列化器中的所有字段都能通过当前查询集直接获取,比如是否有自定义字段方法访问了Post模型中未被预加载的属性。验证聚合查询的影响
可以尝试暂时去掉comments_count和likes_count的annotate操作,看额外查询是否消失,逐步定位问题点。
内容的提问来源于stack exchange,提问作者Antony_K
相关产品推荐
相关产品推荐

