如何在Django中进行左外部联接QuerySet-多对一

时间:2019-04-05 16:30:55

标签: django django-queryset django-orm

我有两个模型:图片(文件名,upload_at)和注释(作者,质量,... fk图片)。

一个图像可以有多个注释,并且一个注释属于一个图像。

我想构建一个查询集,以获取满足某些条件的所有注释(包括与图像的关系,以便我也可以显示图像字段)。

直到这里一切都很好,但是我还要显示没有创建注释的图像(左外连接),并且不确定如何继续执行此操作?

为澄清起见,我试图获取数据,以便可以建立一个像这样的表:

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.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行:image1,注释2等),而不必做图像。 annotation_set ...,因为它不符合我的需求。

任何建议将不胜感激。

谢谢!

1 个答案:

答案 0 :(得分:2)

如果需要外部连接,则必须正确假设它是左连接。因此,您必须从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"]}')