如何合并来自同一模型的两个查询集而不对其进行排序

时间:2019-05-25 15:50:52

标签: python django django-queryset

我已经从同一模型创建了两个查询集,并将它们合并为一个查询集。但是不想对新创建的查询集进行任何排序。我希望我的queryset元素列为我如何合并它们。

queryset1  = modelA.objects.filter(id=modelB.rel_id)
queryset2  = modelA.objects.exclude(id=modelB.rel_id)
queryset = queryset1 | queryset2

我希望的输出为

queryset = <QuerySet [<modelA: YY>, <modelA: XX>, <modelA: ZZ>]>

因为modelA:YY是queryset1,所以我将其合并为第一个元素 但是结果是:

queryset = <QuerySet [<modelA: XX>, <modelA: YY>, <modelA: ZZ>]>

再次按modelA id订购。甚至我都没有在modelA和新的查询集中设置任何顺序。

1 个答案:

答案 0 :(得分:2)

您应在此处使用union(..) [Django-doc]函数,例如:

queryset = modelA.objects.filter(id=modelB.rel_id).union(
    modelA.objects.exclude(id=modelB.rel_id),
    all=True
)

or | [Django-doc]相反,如文档所述:

  

使用 SQL OR运算符组合两个查询集。

     

以下等同:

Model.objects.filter(x=1) | Model.objects.filter(y=2)
from django.db.models import Q
Model.objects.filter(Q(x=1) | Q(y=2))

话虽如此,如果您想最后指定modelB.rel_id,则可以执行以下操作:

from django.db.models import BooleanField, ExpressionWrapper, Q

modelA.objects.annotate(
    rel_to_b=ExpressionWrapper(
        Q(id=modelB.rel_id),
        output_field=BooleanField()
    )
).order_by('rel_to_b')

因此,我们在此处用额外的属性ModelA注释rel_to_b,如果对象与B相关,则该属性将为True,并且由于{ {1}}的排序晚于True,这将是最后一行。

这将产生如下查询:

False