gpt4 book ai didi

与.annotate()结合使用时,Django queryset union似乎无法正常工作

转载 作者:行者123 更新时间:2023-12-04 04:38:12 24 4
gpt4 key购买 nike

我有以下查询集:

photos = Photo.objects.all()

我筛选出两个查询:

a = photos.filter(gallery__name='NGL')
b = photos.filter(gallery__name='NGA')

我将它们加在一起,它们形成一个新的更大的查询集:

c = a | b

实际上, a + b的长度等于 c:

a.count() + b.count() == c.count()
>>> True

到现在为止还挺好。但是,如果我引入 .annotate(),那么 |似乎不再起作用:

a = photos.annotate(c=Count('label').exclude(c__lte=4)
b = photos.filter(painting=True)
c = a | b
a.count() + b.count() == c.count()
>>> False

即使正在使用 .annotate(),如何合并查询集?请注意,查询一和查询二均按预期的方式工作,仅当使用 |组合查询时,它似乎才出现错误。

最佳答案

组合查询集的管道|或&符&实际上将ORAND放入SQL查询中,因此看起来很像组合。

one = Photo.objects.filter(id=1)
two = Photo.objects.filter(id=2)
combined = one | two

print(combined.query)
>>> ... WHERE ("photo_photo"."id" = 1 OR "photo_photo"."id" = 2)...

但是,当您结合使用更多过滤器并将其排除在外时,您可能会注意到,由于这一点,它将给您带来奇怪的结果。这就是为什么当您比较计数时它不匹配的原因。

如果使用 .union(),则必须具有具有相同数据类型的相同列,因此必须注释两个查询集。有关 .union()的信息

  • SELECT statement within .UNION() must have the same number of columns
  • The columns must also have similar data types
  • The columns in each SELECT statement must also be in the same order


您必须记住,不确定数量的参数的pythons参数 kwargs是字典,因此,如果要对多个注释使用注释,则不能确保列的顺序正确。您可以通过链接注释命令解决此问题。
 # printed query of this won't be consistent
photo_queryset.annotate(label_count=Count('labels'), tag_count=Count('tags'))
# this will always have same order of columns
photo_queryset.annotate(label_count=Count('labels')).annotate(tag_count=Count('tags'))

然后,您可以使用 .union(),它不会弄乱注释的结果。另外 .union()应该是最后一个方法,因为在 .union()之后,您不能使用类似 filter的方法。如果要保留重复项,请使用 .union(qs, all=True),因为 .union()具有默认的 all=False并在queryset上调用 DISTINCT
photos = Photo.objects.annotate(c=Count('labels'))
one = photos.exclude(c__lte=4)
two = photos.filter(painting=True)
all = one.union(two, all=True)
one.count() + two.count() == all.count()
>>> True

那么它应该像您所描述的那样工作

关于与.annotate()结合使用时,Django queryset union似乎无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48028411/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com