django - 如何在 Django 中执行 LEFT OUTER JOIN QuerySet - 多对一
问题描述
我有两个模型:图像(文件名,uploaded_at)和注释(作者,质量,... fk Image)。
一个 Image 可以有多个 Annotation,一个 Annotation 属于一个图像。
我想构建一个查询集来获取满足某些条件的所有注释(包括与图像的关系,以便我也可以显示图像字段)。
一切都很好,直到这里,但我还想显示没有创建注释的图像(左外连接),不知道我该如何继续这样做?
为了澄清我正在尝试获取数据,以便可以构建这样的表:
Image name, Image date, Annotation author, Annotation Quality
image 1 , 2019 , john , high
image 2 , 2019 , doe , high
image 3 , 2019 , null , null
image 4 , 2014 , doe , high
也许我使用了错误的方法,我使用 Annotation 作为主要模型,但是我似乎没有办法显示没有 Annotation 的图像,因为没有 Annotation,这是有道理的。这就是我正在做的事情:
Annotation.objects.select_related('image').filter(Q(image__isnull=True)
| Q(other condition))
但是,如果我使用 Image 作为主模型,则关系是一个图像的许多注释,所以我不能使用 select_related,我不确定 prefetch_related 是否适合我需要的东西。我不知道如何正确获取数据。我试过这个:
Image.objects.prefetch_related('annotations').filter(Q(annotations__isnull=True) | Q(other condition))
prefetch_related 似乎对查询没有任何影响,而且我希望将注释数据放在平面/同一行中(即第 1 行:图像 1,注释 1;第 2 行:图像1,注释 2,等),而不必做图像。annotation_set ... 因为那不符合我的需要。
解决方案
如果您需要一个外连接,它必须是一个左连接,正如您正确假设的那样。所以你必须从Image
模型开始。要获得平面表示而不是嵌套Annotation
对象,请使用values(),它返回字典的查询集(而不是模型对象):
queryset_of_dictionaries = (Image.objects
.filter(Q(annotations__isnull=True) | Q(other condition))
.values('name', 'date', 'annotations__author', 'annotations__quality',
# etc. – you have to enumerate all fields you need
)
# you'll probably want the rows in a particular order
.order_by(
# a field list like in values()
)
)
# accessing the rows
for dic in queryset_of_dictionaries:
print(f'Image name: {dic["name"]}, quality: {dic["annotations__quality"]}')
推荐阅读
- javascript - 如何在数据表中的按钮名称上添加选择过滤器
- android - 我们可以用我们的应用程序关闭/终止另一个应用程序吗?
- linux - 在 dockerfile 中运行的 dotnet watch 不起作用
- html - 用文本悬停时展开侧边栏
- node.js - 检索数组中子文档的 ._id
- python - 如何在 python 中获得高于和低于平均值的值?
- swift - 如何在 SwiftUI/Combine 中将订阅者附加到状态或绑定?
- typescript - 如何在 beforeEach (Knex) 中模拟 Knex
- angular - ng-content Angular中的ng-template
- database - BigQuery GENERATE_UUID() 和 CTE