[英]How can I filter __in django ORM by records list?
我希望這樣的查詢:
SELECT field1, field2, field3
FROM mytable
WHERE (field1, field2) NOT IN(
(1, 1),
(2, 2)
);
django==1.9.13
我目前的解決方案是:
qs = MyTable.objects.all()
for (field1, field2) in data: # List[Tuple[int, int]]
qs = qs.exclude(field1=field1, field2=field2)
如果您真的需要,您可以使用 ORM 實現幾乎精確的 SQL 查詢。
from django.db.models import Func, Field, Lookup
class Tuple(Func):
function = ''
template = '(%(expressions)s)'
@Field.register_lookup
class NotIn(Lookup):
lookup_name = 'not_in'
def as_sql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return '%s NOT IN %s' % (lhs, rhs), params
qs = (MyTable.objects.annotate(tup_fields=Tuple('field1', 'field2', output_field=Field()))
.filter(tup_fields__not_in=data))
這將產生 SQL 之類的
SELECT field1, field2, field3, (field1, field2) as tup_fields
FROM mytable
WHERE ((mytable.field1, mytable.field2) NOT IN ((1, 1), (2, 2)));
您可以不使用NotIn(Lookup)
class 並執行.filter(~Q(tup_fields__in=data))
。 這將生成一個類似於NOT (field1, field2) IN (...)
的 where 子句。
您也可以按照自己的方式進行操作,這可能很好。 生成的SQL不同,但結果是一樣的。 我不確定是否存在對您很重要的性能差異。
在這里你可以這樣做
from django.db.models import Q
query = Q()
for (field1, field2) in data: # List[Tuple[int, int]]
query.add(Q(field1=field1, field2=field2), Q.OR)
qs = MyTable.objects.exclude(query)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.