django - 预取一对多关系的特定项目

问题描述

假设我有以下简单模型。一个 BlogPost 可以有多个 BlogPostimages。 BlogPostimages 有一个字段,用于指定图像的顺序。 order=1的图片定义为预览图片

我的目标:对于给定的 BlogPost 查询集(应用了各种过滤器),我想预取相应的预览图像(即 order=1)

from django.db import models

class BlogPost(models.Model):
    name = models.CharField(max_length=50)

class BlogPostimage(models.Model):
    image = models.ImageField()
    order = models.IntegerField()
    blogpost = models.ForeignKey(
        BlogPost,related_name="images",on_delete=models.CASCADE,)

第一次尝试:预取所有图像

results = BlogPost.objects.filter(...).prefetch_related("images").all()

for result in results:
    # 1.1 Triggers query for each blogpost
    preview_image = result.images.filter(order=1)

    # 1.2 Prefetch works,no extra query,but seems inefficient to needlessly iterate over all images
    for image in result.images.all():
        if image.order == 1:
             preview_image = image

第二次尝试:仅预取预览图像

sq = (BlogPostimage.objects
        .filter(blogpost=models.OuterRef('pk'),order=1)
        .values("image")
)

results = (BlogPost.objects.filter(...)
    .annotate(_preview_image=models.Subquery(sq,output_field=models.CharField()))
)

for result in results:
    # 2.1 No extra query,but only the image name
    preview_image = result._preview_image

如何预取预览图像并让数据库完成工作?即:我有 100 篇博文符合我的过滤条件。我希望在一个查询中包含所有 100 篇博文和预览图像,而不是 1+100

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)