2

我需要从查询集中排除一些结果。这样做的条件是,我想排除belong_to特定对象列表的所有记录,但包括第二个值不是特定值的那些记录(即使记录属于排除的记录之一)。

在 SQL 中,我想象这看起来像:

SELECT * FROM some_table WHERE NOT (belongs_to_id IN [1,2,3] AND NOT foo=bar)

我期待这个工作:

qs.exclude(Q(belongs_to__id__in=[1,2,3]) & ~Q(foo=bar))

但是,当我检查结果时connection.queries,django 似乎省略了该~Q(foo=bar)部分。

作为参考,这将在纯 Python 中做同样的事情:

included_ids = qs.filter(foo=bar).values_list('id', flat=True)
excluded_ids = qs.filter(belongs_to__id__in=[1,2,3]).values_list('id', flat=True)
filtered_excluded_ids = [x for x in excluded_ids if not x in included_ids]
new_qs = qs.exclude(id__in=filtered_excluded_ids)

我想避免使用这个解决方案,因为它会导致额外的不必要的查询。

4

1 回答 1

1

鉴于 QI 的意外结果认为您应该使用额外的

qs.extra(where=['NOT ("customer_customer"."belongs_to_id" IN [%s] AND NOT "customer_customer"."sales_rep_id" = %d)'%(','.join(your_list),bar)])

有时 Django 查询语法本身无法表达复杂的 WHERE 子句(它甚至可能取决于 db 后端......),但正如我所说的这种行为很奇怪。

并且,如果其他任何事情都失败了(例如,如果您的查询将变得更加复杂),您可能会继续使用raw

于 2013-01-28T22:29:38.090 回答