Django使用元组列表过滤多个列

时间:2014-06-02 09:17:20

标签: sql django-models

我有一个包含2个字段的简单模型:

class Simple(Model)
    class Meta:
        index_together = True

    a = IntField()
    b = IntField()

我想为a,b的值元组生成SQL查询。 e.g。

select * 
from SimpleModel 
where (a,b) in ((1,1), (4,8), ...)

我知道如何创建类似的东西:

select * 
from SimpleModel 
where ((a = 1 and b = 1) or (a = 4 and b = 8))

这在逻辑上是相同的,但我认为我的数据库在可能值的数量非常大(我使用Postgresql)时有问题,查询本身也要长得多,所以它在网络上更重,并且可能更难以正确地分析和读取它(即在这种情况下使用复合索引)。

所以,问题是,我可以让Django以第一种形式创建查询吗?

谢谢!

2 个答案:

答案 0 :(得分:6)

@Wolph答案是正确的,但我会这样做

tuple_of_tuples = ((1,1), (4,8))
Simple.objects.extra(where=['(a,b) in %s'], params=[tuple_of_tuples])

点击此处查看有关传递元组而不是列表的信息

Passing lists or tuples as arguments in django raw sql

对于我引用Django文档的params https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.extra

  

<强> PARAMS

     

上面描述的 where 参数可以使用标准的Python数据库   字符串占位符 - &#39;%s&#39; 表示数据库引擎的参数   应自动报价。 params 参数是任何额外的列表   要替换的参数。

     

示例:

     

Entry.objects.extra(where=['headline=%s'], params=['Lennon'])

     

始终使用参数,而不是将值直接嵌入其中,因为   参数将确保根据您的报价正确引用值   特别是后端。例如,报价将被正确转义。

答案 1 :(得分:1)

是的,但仅*使用where的{​​{1}}参数:https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.extra

这样的事情应该做:

extra

*如果您创建自定义数据库类型,您应该能够定义自定义运算符,因此...可能能够解决它。我会稍微google一下:)