Django在BooleanField上注释

mik*_*725 7 sqlite django postgresql django-queryset

我有以下型号:

class Foo(models.Model):
    pass

class Bar(models.Model):
    foo = models.ForeignKey(Foo)
    is_successful = models.BooleanField()
Run Code Online (Sandbox Code Playgroud)

我想获得的所有foo对象与注释如果所有的bar关联对象foo的对象有is_successful作为True

到目前为止,我的查询集是:

foos = Foo.objects.all().annotate(all_successful=Min('bar__is_successful'))
Run Code Online (Sandbox Code Playgroud)

all_successful注释的想法是,如果所有is_successful行的最小值都是1,那么所有行的最小值必须是True(假设0False1True).所以知道我可以像这样使用查询集:

foo = foos[0]

if foo.all_successful == 1:
    print 'All bars are successful'
else:
    print 'Not all bars are successful'
Run Code Online (Sandbox Code Playgroud)

这在sqlite中效果很好但是它在PostgreSQL中失败,因为PostgreSQL无法MIN在布尔列上执行聚合.我想这适用于sqlite,因为sqlite将bools视为整数,因此它可以执行聚合.

我的问题是如何在不将我的is_successful字段转换为的情况下使这个查询集在PostgreSQL中工作IntegerField

感谢名单

Dav*_*xor 13

我知道这是一个老问题,但最近我遇到了这个问题.Django v1.8现在内置了对case/when的支持,因此你可以使用ORM而不是使用自定义SQL进行攻击.

https://docs.djangoproject.com/en/1.8/ref/models/conditional-expressions/#case

Foo.objects.annotate(
    all_successful=Case(
        When(bar__is_successful=False, then=False),
        When(bar__is_successful=True, then=True),
        default=False,
        output_field=BooleanField()
    ))
Run Code Online (Sandbox Code Playgroud)

我没有试过这个,但在最近的一个项目中,类似的东西对我有用.