在组合两个查询集后保留queryset注释

时间:2017-08-09 15:50:01

标签: python django django-queryset

我目前正在努力应对带注释的django查询集的行为以及包含的运算符和&

我有这样的模特:

class Property(models.Model):
    value = models.IntegerField(null=True)

    obj = PropertyManager()

class Profile(models.Model):
    name = models.CharField()
    values = models.ManyToManyField(Property)

class PropertyManager(models.Manager):
    def included(self, profile):
        super(PropertyManager, self).filter(Q(property__profile=profile)).annotate(included_value=Value('true', output_field=CharField()))

    def excluded(self, profile):
        super(PropertyManager, self).filter(~Q(property__profile=profile)).annotate(included_value=Value('false', output_field=CharField()))

    def included_excluded(self, profile):
        return (self.excluded(profile) | self.included(profile)).distinct()

我天真地期望included_excluded函数返回两个查询集的连接查询集及其注释,如:

property_id | included_value
------------|---------------
          1 |   true
          2 |   false

但事实证明,注释在我的示例中被覆盖:

j = Profile.objects.get(id=1)
exc = Property.obj.excluded(profile=j)
inc = Property.obj.included(profile=j)
all = Property.obj.included_excluded(profile=j)

len(inc)  => 14
len(exc)  => 17
len(all)  => 31

all.values_list("included_value")  => <QuerySet [('false',)]>
exc.values_list("included_value")  => <QuerySet [('false',)]>
inc.values_list("included_value")  => <QuerySet [('true',)]>
正如我所料,

all显然不是注释中的所有正确值。

所以我想知道,如果有一种方法可以连接两个查询集并保留我之前制作的注释

1 个答案:

答案 0 :(得分:0)

从Django 1.8起,你可以这样做:

from django.db import models
from django.db.models import Case, When

def included_excluded(self, profile):
    return super(PropertyManager, self).annotate(
        included_value=Case(
            When(property__profile=profile, then='true'),
            default='false', output_field=models.CharField()
        )
    )

如果您需要单独使用它们,那么稍后您可以过滤此查询集:PropertyManager().included_excluded(profile).filter(included_value='true')