【问题标题】:Django QuerySet union operator are not commutative after annotated filter带注释的过滤器后,Django QuerySet 联合运算符不可交换
【发布时间】:2014-12-28 12:20:55
【问题描述】:

...并返回意外结果(在 Django 1.6.5 中)

我的模型.py

class Member(models.Model):
    ...
class Donation(models.Model):
    year = models.PositiveSmallIntegerField()
    cheque_amount = models.DecimalField(default=0, max_digits=8, decimal_places=2)
    donor = models.ForeignKey(Member)
    ...
class SpecialTitle(models.Model):
    chair_title = models.CharField(max_length=128, blank=True)
    member = models.OneToOneField(Member)
    ...

我想在我的一个管理过滤器中合并两个查询集

donors = queryset.filter(
    donation__year__exact=2014
).annotate(sum_donation=Sum('donation__cheque_amount')).filter(sum_donation__gte=1000)

chairs = queryset.filter(specialtitle__chair_title__iendswith='Chair')

这是令人费解的部分(在 Django manager shell 中)

>>> donors | chairs == chairs | donors
False
>>> donors.count(); chairs.count()
189
17
>>> (donors | chairs).count(); (chairs | donors).count()
193
291
>>> (donors | chairs).distinct().count(); (chairs | donors).distinct().count()
193
207

而且没有一个是正确的结果。我希望设置操作是

>>> set(donors) | set(chairs) == set(chairs) | set(donors)
True
>>> set(donors) & set(chairs) == set(chairs) & set(donors)
True
>>>

它们会返回正确的结果。但是,Django 管理过滤器需要 QuerySet,而不是 python 集(或列表)

这是为什么?如何在带注释的过滤器后获得 Django QuerySet(相同类型)的正确联合? 谢谢你。

【问题讨论】:

  • 我刚遇到一个类似的问题——a | b != b |一种。看起来 a 的 HAVING 子句也适用于我期望独立的 b。

标签: python-2.7 django-queryset


【解决方案1】:

看来我别无选择,只能使用 python set union 运算符并再次访问数据库以获得所需的结果。

donors = queryset.filter(
    donation__year__exact=2014
).annotate(sum_donation=Sum('donation__cheque_amount')).filter(sum_donation__gte=1000)

chairs = queryset.filter(specialtitle__chair_title__iendswith='Chair')

result = queryset.filter(pk__in=[person.id for person in set(donors) | set(chairs)])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-07
    • 2019-08-03
    • 2012-04-05
    • 2023-03-30
    • 2014-07-13
    • 2011-06-04
    • 1970-01-01
    • 2011-06-22
    相关资源
    最近更新 更多