Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
BooleanField上的Django注释_Django_Sqlite_Postgresql_Django Queryset - Fatal编程技术网

BooleanField上的Django注释

BooleanField上的Django注释,django,sqlite,postgresql,django-queryset,Django,Sqlite,Postgresql,Django Queryset,我有以下型号: class Foo(models.Model): pass class Bar(models.Model): foo = models.ForeignKey(Foo) is_successful = models.BooleanField() 如果与foo对象关联的所有bar对象都具有成功的asTrue 到目前为止,我的查询集是: foos = Foo.objects.all().annotate(all_successful=Min('bar__is

我有以下型号:

class Foo(models.Model):
    pass

class Bar(models.Model):
    foo = models.ForeignKey(Foo)
    is_successful = models.BooleanField()
如果与
foo
对象关联的所有
bar
对象都具有
成功的
as
True

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

foos = Foo.objects.all().annotate(all_successful=Min('bar__is_successful'))
all\u successful
注释的思想是,如果all
行的最小值为1,则所有行都必须为
True
(假设
0
False
1
True
)。所以知道我可以像这样使用queryset:

foo = foos[0]

if foo.all_successful == 1:
    print 'All bars are successful'
else:
    print 'Not all bars are successful'
这在sqlite中非常有效,但在PostgreSQL中失败,因为PostgreSQL无法在布尔列上执行
MIN
aggregate。我猜这在sqlite中是有效的,因为sqlite将布尔值视为整数,因此它可以执行聚合

我的问题是如何在PostgreSQL中使用此查询集,而不将我的
是否成功
字段转换为
整型字段

Thanx的灵感来源于我建议对Bar类使用自定义管理器,而不是注释

class BarManager(models.Manager):
    def get_all_successful_foos_ids(self):
        from django.db import connection
        cursor = connection.cursor()
        cursor.execute("""
            SELECT foo, COUNT(*)
            FROM yourapp_bar
            GROUP BY 1
            WHERE is_successful = true""")  # <-- you have to write the correct table name here
        result_list = []
        for row in cursor.fetchall():
            if row[1] > 0:
                result_list.append(row[0])
        return result_list

class Bar(models.Model):
    foo = models.ForeignKey(Foo)
    is_successful = models.BooleanField()
    objects = BarManager()  # here I'm changing the default manager

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


我还没有尝试过这个方法,但在最近的一个项目中类似的方法对我起到了作用。

Thanx的想法,但这不是我想要的,因为你的建议只是过滤查询集,而我正在寻找如何注释我的foo模型。我写了另一个答案,用一种更简单的方法,应该会给你预期的注释(我没有时间测试它,但我希望它会让您走上正确的方向)这太棒了。我正在寻找一种使用SQL“CASE WHEN”的好方法在Django中,这是一个很好的方法。这是一个更好的方法,很好的观点!感谢您的贡献!您的语法比实际文档更容易理解,谢谢!代码块中缺少了最后一个
。另外,请将最后一个kwarg
output\u field=BooleanField()
添加到
Case()
调用中。所做的更改:
foos = foo.objects.filter(id__in=Bar.objects.get_all_successful_foos_ids())
foos = Foo.objects.extra(select={'all_successful': 'CASE WHEN COUNT(b.foo) > 0 THEN 0 ELSE 1 END FROM yourapp_bar as b WHERE b.is_successful = false and b.foo = yourapp_foo.id' })
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()
    ))