Django in / not in query


100

django에서 'not in'스타일 쿼리를 작성하는 방법을 알아 내려고합니다. 예를 들어 내가 생각하는 쿼리 구조는 다음과 같습니다.

select table1.* 
from table1
where table1.id not in 
(
  select table2.key_to_table1
  from table2 
  where table2.id = some_parm 
)

django 구문은 table1 및 table2라는 모델을 가정하면 어떻게 생겼습니까?

답변:


164
table1.objects.exclude(id__in=
    table2.objects.filter(your_condition).values_list('id', flat=True))

제외 기능은 Not요청 하는 연산자 처럼 작동 합니다. 이 속성 flat = Truetable2쿼리에를 value_list한 수준 목록으로 반환하도록 지시 합니다. 그래서 ... 끝에 IDstable2에서 목록을 얻습니다. 에서 조건을 정의하기 위해 사용자 table1가 될 것이며 제외 기능에 의해 거부됩니다.


3
또한 목록 생성자 [table2 ...]-> list (table2 ...)에 문제가있었습니다.
RickyA 2011

3
수정 : table1.objects.exclude (id__in = table2.objects.filter (your_condition) .values_list ( 'ID', 평면 = 참))
리처드

1
이 솔루션을 사용하려고했지만 문제가 발생 했으므로 다른 사람에게 발생하면 ... Objs=Tbl1.objects.filter(...); IDs=Objs.values_list('id', flat=True); Objs.delete(); Tbl2.objects.filter(id__in=IDs')ID가 실제로 QuerySet 개체이기 때문에 작동하지 않았습니다. 원래 행을 삭제하면 더 이상 다른 쿼리와 함께 작동하지 않습니다. 이 솔루션은있다 Tbl2.objects.filter(id__in=list(IDs))- 목록으로 바꿀
Dakusan

1
필터가 "수 (XX) == 전년 동기 대비 필요"와 같은 경우, 상황에 따라 더 이상의 100 배 빠른 사용에의 annotate()(timeit는 0.00514069400014705 대 나에게 1.0497902309998608 준)
올리비에 뇌교

10

이 모델 :

class table1(models.Model):
    field1 = models.CharField(max_length=10)      # a dummy field

class table2(models.Model):
    key_to_table1 = models.ForeignKey(table1)

다음을 사용하여 원하는 것을 얻어야합니다.

table1.objects.exclude(table2=some_param)

1
이것은 잠재적으로 db에서 불필요하게 많은 레코드를 가져올 수 있습니다.
Jay Taylor

5
table1.objects.extra(where=["table1.id NOT IN (SELECT table2.key_to_table1 FROM table2 WHERE table2.id = some_parm)"])

1

Django 쿼리에 대한 사용자 지정 조회를 작성할 수 있습니다.

로부터 문서 : ". 간단한 사용자 정의 조회와하자의 시작 우리는 사용자 정의 조회 작성합니다 NE 하는 반대 작동 정확한을 . Author.objects.filter (name__ne = '잭') 는 SQL로 변환됩니다 "author"."name" <> 'Jack'"

from django.db.models import Lookup

class NotEqual(Lookup):
    lookup_name = 'ne'

    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 <> %s' % (lhs, rhs), params

-16
[o1 for o1 in table1.objects.all() if o1.id not in [o2.id for o2 in table2.objects.filter(id=some_parm)]]

또는 더 나은

not_in_ids = [obj.id for obj in table2.objects.filter(id=some_parm)]
selected_objects = [obj for obj in table1.objects.iterator() if obj.id not in not_in_ids]

12
테이블의 모든 행을 반복합니다. gg
Rebs
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.