我正在一个复杂的数据模型上建立一个复杂的查询集。查询集必须返回带有注解ann
的模型对象A
的选择。
为了计算ann
,我需要一个辅助注解aux
,但是在查询集的最终结果中不允许存在aux
。
qs = A.objects.filter(...) # complicated
qs = qs.annotate(aux=...) # complicated
qs = qs.annotate(ann=Case(
When(condition=Q(aux=0),
then Value('some')),
When(condition=Q(aux_gt=0),
then Value('other'))))
如何返回带有ann
但不带aux
的qs
?
(或者:如果aux
是一个计数,而ann
区分零和非零aux
,那么是否有更好的方法来解决整个问题?)
3条答案
按热度按时间cgyqldqp1#
Django 3.2引入了一个功能来专门解决这个问题:
https://docs.djangoproject.com/en/3.2/ref/models/querysets/#alias
alias()
的工作方式类似于annotate()
,除了其他查询集方法,如annotate()
:它不会停留在最终输出中。wr98u20j2#
丑陋的黑客:
一个简单的方法是将
aux
也重命名为ann
。这样,第二个注解将覆盖第一个注解,第一个注解将不再存在于输出中。这似乎起作用了。在SQlite和PostgreSQL上使用Django 1.11进行测试。
但一定有更好的办法,拜托。
lymgl2op3#
它没有文档记录,但有一个
QuerySet().query.annotations
字典,您可以操作它来从结果中删除注解:它既适用于您提到的“辅助注解”,也适用于过滤。例如,如果你只是想过滤它们,你可以在最后删除所有的注解:
但是如果你能负担得起使用较新的django(3.2+),那么就像另一个答案中建议的那样使用
qs.alias()
:https://stackoverflow.com/a/69486332/952437