我已经从同一模型创建了两个查询集,并将它们合并为一个查询集。但是不想对新创建的查询集进行任何排序。我希望我的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和新的查询集中设置任何顺序。
答案 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