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

ida*_*alz 4 sql django-models

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

class Simple(Model)
    class Meta:
        index_together = True

    a = IntField()
    b = IntField()
Run Code Online (Sandbox Code Playgroud)

我想为值的元组生成一个SQL查询a,b.例如

select * 
from SimpleModel 
where (a,b) in ((1,1), (4,8), ...)
Run Code Online (Sandbox Code Playgroud)

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

select * 
from SimpleModel 
where ((a = 1 and b = 1) or (a = 4 and b = 8))
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢!

Nou*_*olf 6

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

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

检查这里有关传递元组而不是列表的信息

在django raw sql中传递列表或元组作为参数

对于params来自Django文档我报价 https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.extra

PARAMS

上面描述的where参数可以使用标准的Python数据库字符串占位符 - '%s'来指示数据库引擎应该自动引用的参数.所述PARAMS参数是要取代的任何额外的参数的列表.

例:

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

始终使用params而不是直接将值嵌入到where中,因为 params将确保根据您的特定后端正确引用值.例如,报价将被正确转义.


Wol*_*lph 2

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

像这样的事情应该做:

Simple.objects.extra(where=['(a,b) in %s' % your_list])
Run Code Online (Sandbox Code Playgroud)

*如果您创建自定义数据库类型,您应该能够定义自定义运算符,因此...也许能够解决它。我会用谷歌搜索一下:)