/ / O operador de união do Django QuerySet não é comutativo após o filtro anotado - python-2.7, django-queryset

O operador de união do QuerySet do Django não é comutativo após o filtro anotado - python-2.7, django-queryset

... e retorna resultados inesperados (no Django 1.6.5)

Meus models.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)
...

Eu gostaria da união dos dois querysets em um dos meus filtros de administrador

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")

Aqui está a parte intrigante (no shell do gerenciador do Django)

>>> 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

E nenhum deles é o resultado correto. Eu esperava que uma operação definida fosse

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

E eles retornam os resultados corretos. No entanto, o filtro de administração do Django exige um QuerySet, não um conjunto de python (ou lista)

Por que é isso? Como obtenho uma união adequada do Django QuerySet (do mesmo tipo) após o filtro anotado? Obrigado.

Respostas:

0 para resposta № 1

Parece que não tive outra escolha senão usar o operador de união set python e acertar o banco de dados novamente para o resultado desejado.

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)])