Django에서 다중 인수가있는 필터와 체인 필터의 차이점은 무엇입니까?
Django에서 다중 인수가있는 필터와 체인 필터의 차이점은 무엇입니까?
답변:
생성 된 SQL 문에서 볼 수 있듯이 일부는 의심 할 수있는 "OR"이 아닙니다. WHERE 및 JOIN이 배치되는 방법입니다.
예제 1 (동일한 조인 된 테이블) : https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships에서
Blog.objects.filter(
entry__headline__contains='Lennon',
entry__pub_date__year=2008)
이렇게하면 이 쿼리에서 기대할 수있는 두 가지 항목이 모두 있는 모든 블로그가 제공됩니다 (entry__headline__contains='Lennon') AND (entry__pub_date__year=2008)
.
결과:
Blog with {entry.headline: 'Life of Lennon', entry.pub_date: '2008'}
예 2 (체인)
Blog.objects.filter(
entry__headline__contains='Lennon'
).filter(
entry__pub_date__year=2008)
이것은 예제 1의 모든 결과를 포함하지만 약간 더 많은 결과를 생성합니다. 먼저 모든 블로그를 (entry__headline__contains='Lennon')
필터링 한 다음 결과 필터에서 필터링하기 때문 (entry__pub_date__year=2008)
입니다.
차이점은 다음과 같은 결과도 제공한다는 것입니다.
여러 항목이있는 단일 블로그
{entry.headline: '**Lennon**', entry.pub_date: 2000},
{entry.headline: 'Bill', entry.pub_date: **2008**}
첫 번째 필터가 평가 될 때 첫 번째 항목 때문에 책이 포함됩니다 (일치하지 않는 다른 항목이 있더라도). 두 번째 필터가 평가되면 두 번째 항목 때문에 책이 포함됩니다.
하나의 테이블 : 그러나 쿼리에 Yuji 및 DTing의 예와 같이 조인 된 테이블이 포함되지 않은 경우. 결과는 동일합니다.
(entry__headline__contains='Lennon')
필터링 한 다음 결과 필터에서 필터링 (entry__pub_date__year=2008)
하기 때문에" "결과에서 나온 결과"가 정확하다면 왜 entry.headline == 'Bill'
.. 노만 entry__headline__contains='Lennon'
아웃 필터를 Bill
예?
"multiple arguments filter-query"의 결과가 "chained-filter-query"와 다른 경우는 다음과 같습니다.
참조 개체 및 관계를 기반으로 참조 개체를 선택하는 것은 일대 다 (또는 다 대다)입니다.
여러 필터 :
Referenced.filter(referencing1_a=x, referencing1_b=y) # same referencing model ^^ ^^
체인 필터 :
Referenced.filter(referencing1_a=x).filter(referencing1_b=y)
두 쿼리 모두 서로 다른 결과를 출력 할 수 있습니다.
referencing-model의 한 행 이상이 referenced-model의Referencing1
동일한 행을 참조 할 수있는 경우Referenced
. 이 경우에 할 수있다Referenced
:Referencing1
이 중 하나를 1 : N (일대) 또는 N : (많은 많은) M 관계 선박.
예:
내 응용 프로그램 my_company
에는 두 가지 모델 Employee
과 Dependent
. 의 직원은 my_company
부양 가족보다 많을 수 있습니다 (즉, 부양 가족은 한 직원의 아들 / 딸이 될 수 있지만 직원은 둘 이상의 아들 / 딸을 가질 수 있습니다).
Ehh, 남편 아내처럼 둘 다 my_company
. 1 : m 예를 들었습니다.
그래서, Employee
참조 모델이 더 많이 참조 할 수있는 참조 Dependent
모델입니다. 이제 다음과 같이 관계 상태를 고려하십시오.
Employee: Dependent: +------+ +------+--------+-------------+--------------+ | name | | name | E-name | school_mark | college_mark | +------+ +------+--------+-------------+--------------+ | A | | a1 | A | 79 | 81 | | B | | b1 | B | 80 | 60 | +------+ | b2 | B | 68 | 86 | +------+--------+-------------+--------------+
Dependent
a1
는 직원을 의미A
하고 종속적b1, b2
참조는 직원을 의미B
합니다.
이제 내 쿼리는 다음과 같습니다.
대학과 학교 모두에서 아들 / 딸이있는 직원이 모두 구별 점수 (예 : 75 % 이상)를 가지고 있습니까?
>>> Employee.objects.filter(dependent__school_mark__gte=75,
... dependent__college_mark__gte=75)
[<Employee: A>]
출력은 'A'종속 'a1'은 대학과 학교 모두에서 구별 표시가 있으며 직원 'A'에 종속됩니다. 참고 'B'는 'B'자녀의 네더가 대학과 학교 모두에서 구별 마크가 있기 때문에 선택되지 않았습니다. 관계형 대수 :
종업원 ⋈ (school_mark> = 75 AND college_mark> = 75) 종속
둘째, 쿼리가 필요한 경우 :
부양 가족 중 일부가 대학과 학교에서 구별 마크가있는 모든 직원을 찾으십니까?
>>> Employee.objects.filter(
... dependent__school_mark__gte=75
... ).filter(
... dependent__college_mark__gte=75)
[<Employee: A>, <Employee: B>]
이번에 'B'는 'B'가 두 명의 자녀 (한 명 이상!)가 있고, 한 명은 학교 'b1'에서 구별 마크가 있고 다른 하나는 대학 'b2'에서 구별 마크가 있기 때문에 선택되었습니다.
필터 순서는 중요하지 않습니다. 위의 쿼리를 다음과 같이 작성할 수도 있습니다.
>>> Employee.objects.filter(
... dependent__college_mark__gte=75
... ).filter(
... dependent__school_mark__gte=75)
[<Employee: A>, <Employee: B>]
결과는 동일합니다! 관계형 대수는 다음과 같습니다.
(직원 ⋈ (school_mark> = 75) 에 따라 다름) ⋈ (college_mark> = 75) 종속
참고 :
dq1 = Dependent.objects.filter(college_mark__gte=75, school_mark__gte=75)
dq2 = Dependent.objects.filter(college_mark__gte=75).filter(school_mark__gte=75)
동일한 결과를 출력합니다. [<Dependent: a1>]
Django에서 생성 한 대상 SQL 쿼리를 확인 print qd1.query
하고 print qd2.query
둘 다 동일합니다 (Django 1.6).
그러나 의미 상 둘 다 나에게 다릅니다 . 첫 번째는 간단한 섹션 σ [school_mark> = 75 AND college_mark> = 75] (종속) 처럼 보이고 두 번째는 느린 중첩 쿼리처럼 보입니다. σ [school_mark> = 75] (σ [college_mark> = 75] (종속)).
필요한 경우 코드 @codepad
btw, 그것은 문서 @ Spanning 다중 값 관계에 제공 됩니다. 방금 예제를 추가했습니다. 새로운 사람에게 도움이 될 것이라고 생각합니다.
대부분의 경우 쿼리에 대해 가능한 결과 집합은 하나만 있습니다.
체인 필터는 m2m을 다룰 때 사용됩니다.
이걸 고려하세요:
# will return all Model with m2m field 1
Model.objects.filter(m2m_field=1)
# will return Model with both 1 AND 2
Model.objects.filter(m2m_field=1).filter(m2m_field=2)
# this will NOT work
Model.objects.filter(Q(m2m_field=1) & Q(m2m_field=2))
다른 예도 환영합니다.
성능 차이가 큽니다. 그것을 시도하고보십시오.
Model.objects.filter(condition_a).filter(condition_b).filter(condition_c)
의외로 느립니다
Model.objects.filter(condition_a, condition_b, condition_c)
효과적인 Django ORM 에서 언급했듯이 ,
- QuerySet은 메모리에 상태를 유지합니다.
- 체이닝은 복제를 트리거하고 해당 상태를 복제합니다.
- 불행히도 QuerySet은 많은 상태를 유지합니다.
- 가능하면 두 개 이상의 필터를 연결하지 마십시오.
연결 모듈을 사용하여 비교할 원시 SQL 쿼리를 볼 수 있습니다. Yuji가 설명했듯이 대부분은 다음과 같이 동일합니다.
>>> from django.db import connection
>>> samples1 = Unit.objects.filter(color="orange", volume=None)
>>> samples2 = Unit.objects.filter(color="orange").filter(volume=None)
>>> list(samples1)
[]
>>> list(samples2)
[]
>>> for q in connection.queries:
... print q['sql']
...
SELECT `samples_unit`.`id`, `samples_unit`.`color`, `samples_unit`.`volume` FROM `samples_unit` WHERE (`samples_unit`.`color` = orange AND `samples_unit`.`volume` IS NULL)
SELECT `samples_unit`.`id`, `samples_unit`.`color`, `samples_unit`.`volume` FROM `samples_unit` WHERE (`samples_unit`.`color` = orange AND `samples_unit`.`volume` IS NULL)
>>>
이 페이지에서 여러 체인 필터를 사용하여 django 쿼리 세트를 동적으로 빌드하는 방법을 찾고 있지만 필터가 AND
대신 유형 이어야하는 경우 Q 객체를OR
사용하는 것이 좋습니다. .
예 :
# First filter by type.
filters = None
if param in CARS:
objects = app.models.Car.objects
filters = Q(tire=param)
elif param in PLANES:
objects = app.models.Plane.objects
filters = Q(wing=param)
# Now filter by location.
if location == 'France':
filters = filters & Q(quay=location)
elif location == 'England':
filters = filters & Q(harbor=location)
# Finally, generate the actual queryset
queryset = objects.filter(filters)
a와 b가 필요한 경우
and_query_set = Model.objects.filter(a=a, b=b)
a와 b가 필요한 경우
chaied_query_set = Model.objects.filter(a=a).filter(b=b)
공식 문서 : https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships
관련 게시물 : Django에서 다중 filter () 연결, 이것이 버그입니까?
예를 들어 관련 개체에 대한 요청이있을 때 차이가 있습니다.
class Book(models.Model):
author = models.ForeignKey(Author)
name = models.ForeignKey(Region)
class Author(models.Model):
name = models.ForeignKey(Region)
의뢰
Author.objects.filter(book_name='name1',book_name='name2')
빈 세트를 반환합니다.
및 요청
Author.objects.filter(book_name='name1').filter(book_name='name2')
'name1'과 'name2'가 모두있는 책이있는 저자를 반환합니다.
자세한 내용은 https://docs.djangoproject.com/en/dev/topics/db/queries/#s-spanning-multi-valued-relationships 를 참조하십시오.
Author.objects.filter(book_name='name1',book_name='name2')
유효한 파이썬도 아닙니다.SyntaxError: keyword argument repeated