두 장고 쿼리 셋의 합집합을 어떻게 찾을 수 있습니까?


92

두 가지 사용자 지정 관리자 메서드가있는 Django 모델이 있습니다. 각각은 객체의 다른 속성에 따라 모델 객체의 다른 하위 집합을 반환합니다.

각 관리자 메서드에서 반환 된 쿼리 집합의 합집합 인 쿼리 집합 또는 개체 목록을 얻을 수있는 방법이 있습니까?


3
(삭제 된 답변에서) 다른 모델의 QuerySet에서 작동하는 변형은이 질문을 참조하십시오. stackoverflow.com/questions/431628/…
rnevius

1
버전 1.11부터 django 쿼리 세트에는 내장 통합 메소드가 있습니다. 나는 미래의 참조에 대한 대답으로 추가 한
호세 Cherian에게

답변:


179

이것은 작동하고 조금 더 깨끗해 보입니다.

records = query1 | query2

중복을 원하지 않는 경우 다음을 추가해야합니다 .distinct().

records = (query1 | query2).distinct()

5
수락 된 답변은 OP가 요청한 것처럼 통합 반복 가능 (정확한 목록)을 반환하지만이 메서드는 쿼리 집합의 진정한 통합을 반환합니다. 이 쿼리 세트는 추가로 작동 할 수 있으며 많은 상황에서 필요합니다.
Krystian Cybulski

5
Django 버그로 인해이 구성은 ManyToManyFields를 처리 할 때 때때로 잘못된 결과를 반환 할 수 있습니다 . 예를 들어,이 records.count()값이보다 큽니다 query1.count() + query2.count(). 이는 분명히 잘못된 것입니다.
Jian

4
@Jian 버그와 djangoproject 문제에 대한 링크로 django 버전을 명확히 할 수 있습니까?
IMFletcher 2013 년

10
레코드 = query1 | query2; records = records.distinct ()는 나에게 정확한 결과를 줄 것입니다
eugene

5
Python에서 연산자를 오버로드 할 수 있습니다. docs.python.org/2/library/operator.html을 참조하십시오 . 그래서 Django가하는 일은 QuerySet 객체를위한 특별한 메소드를 만드는 것입니다. 여기에 코드를 참조하십시오 github.com/django/django/blob/master/django/db/models/...QuerySet 클래스에 대한 방법을 제공 __and__하고 __or__호출 할 때 그 &또는 |운영자가 둘 사이에 사용되는 QuerySet도에 사용되는 객체 ( Q클래스뿐만 아니라 ).
Jordan Reiter 2013 년

49

버전 1.11 부터 django 쿼리 세트에는 내장 통합 메소드가 있습니다.

q = q1.union(q2) #q will contain all unique records of q1 + q2
q = q1.union(q2, all=True) #q will contain all records of q1 + q2 including duplicates
q = q1.union(q2,q3) # more than 2 queryset union

더 많은 예제를 보려면 이에 대한 내 블로그 게시물 을 참조하십시오 .


나는 all = True가 작동하도록 할 수 없습니다. 클라이언트에 반환하기 전에 내 쿼리 세트를 세트로 캐스팅하는 것으로 끝났습니다.
Braden Holt

1
@BradenHolt, all = True는 중복 레코드를 포함 함을 의미합니다. 세트로 캐스트하지 않으려면 all = True를 제거하면됩니다.
Jose Cherian

이것이 작동하지 않으면 DjangoFilterBackend, 어떻게 Union과 DjangoFilterBackend를 사용할 수 있습니까?
nesalexy

불행히도, 이것은 모델의 Meta에 정의 된 기본 순서를 가진 모델에서는 작동하지 않는 것 같습니다. 이들을 .union과 결합하려고 할 때마다 다음 오류가 표시됩니다. "복합 문의 하위 쿼리에서 ORDER BY가 허용되지 않습니다."
jrial

4

'query1 | 대신'query1.union (query2) '를 사용하는 것이 좋습니다. query2 '; 위의 두 가지 방법에서 다른 결과를 얻었으며 이전 방법은 내가 기대 한 것입니다. 다음은 내가 본 것입니다.

print "union result:"
for element in query_set1.union(query_set2):
    print element

print "| result:"
for element in (query_set1 | query_set2):
    print element

결과:

union result:
KafkaTopic object
KafkaTopic object
KafkaTopic object
KafkaTopic object
KafkaTopic object

| result:
KafkaTopic object
KafkaTopic object

1
코드 이미지가 아닌 코드를 붙여 넣으십시오. 이미지의 텍스트는 검색 할 수 없으며 확인을 위해 편집기에 복사 / 붙여 넣기 할 수 없으며 필요한 것보다 더 많은 공간을 차지합니다. 백틱을 사용하여 코드를 코드로 표시하면 올바른 형식이 지정됩니다. 텍스트 입력 상자 옆에있는 "도움말"링크를 참조하십시오.
jrial

업데이트 해 주셔서 감사합니다. :)
jrial
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.