source

쿼리 후 쿼리 집합을 필터링할 수 있습니까? 장고

manycodes 2023. 10. 28. 08:03
반응형

쿼리 후 쿼리 집합을 필터링할 수 있습니까? 장고

질문이 이상하게 들린다면 죄송합니다.나는 단지 내가 이미 쿼리 세트를 가지고 있는데 새로운 쿼리 세트를 만드는 것이 가능한지 궁금합니다.

예를 들면 여기...

 everyone = User.objects.filter(is_active=True)  # this would of course return all users that's active
 not_deleted = User.objects.filter(is_active=True, is_deleted=False)  # return user that's active and not deleted
 is_deleted = User.objects.filter(is_active=True, is_deleted=True)  # return user that's active and is already deleted

내 질문은...not_deleted그리고.is_deleted둘 다 활성화되어 있는 것은 다음과 같습니다.everyone사용할 수 있는 방법이 있습니까?everyone그리고 나서 어떻게든 걸러낼 겁니다is_deleted=True아니면is_deleted=False? 그렇다면 이것이 가능하다면 쿼리가 더 빠르고 더 좋을 것으로 생각합니다.

세 변수 모두everyone,not_deleted그리고.is_deleted그러면 다른 용도로 사용될 겁니다

제 질문을 조용히 했길 바랍니다.

미리 감사드립니다.

예, 기존 쿼리 세트를 재사용할 수 있습니다.

everyone = User.objects.filter(is_active=True)
active_not_deleted = everyone.filter(is_deleted=False)
active_is_deleted = everyone.filter(is_deleted=True)

실제로 이 코드 블록은 Django QuerySets가 게으르게 평가되기 때문에 데이터베이스에 대한 쿼리를 실행하지도 않습니다.제 말은 실제로 값이 필요할 때까지 쿼리를 데이터베이스로 전송하지 않는다는 것입니다.데이터베이스와 대화하는 예제가 있습니다.

everyone = User.objects.filter(is_active=True)  # Building SQL...
active_not_deleted = everyone.filter(is_deleted=False)  # Building SQL...
active_is_deleted = everyone.filter(is_deleted=True)  # Building SQL...

# Example of the whole queryset being evaluated
for user in everyone:
    # This will execute the query against the database to return the list of users
    # i.e. "select * from user where is_active is True;"
    print(user)

# Example of using iterator to evaluate one object at a time from the queryset.
for user in active_not_deleted.iterator():
    # This will execute the query for each result, so it doesn't
    # load everything at once and it doesn't cache the results.
    # "select * from user where is_active is True and is_deleted is False limit 1 offset 0;"
    # The offset is incremented on each loop and another query is sent to retrieve the next user in the list.
    print(user)

읽기를 권장합니다.

이 답변에 추가로, 당신은 하나의 질의를 한 다음, 당신이 정말 원한다면 파이썬에서 필터링할 수 있습니다.쿼리 집합이 아니기 때문에 목록에 대한 후속 필터링을 수행할 수 없습니다.

everyone = User.objects.filter(is_active=True)
active_not_deleted = list(filter(lambda user: user.is_deleted is False), list(everyone))
active_is_deleted = list(filter(lambda user: user.is_deleted is True), list(everyone))

이 마지막 예에서,everyone는 쿼리 집합이고,active_not_deleted그리고.active_is_deleted파이썬은 사용자 객체의 목록입니다.everyone쿼리 세트는 처음에 한 번만 평가됩니다.list(everyone)호출한 다음 결과가 캐시됩니다.

1. 체인필터법

not_deleted = User.objects.filter(active=True).filter(is_deleted=False)

@코리 매든은 이미 대답했습니다.User.objects.filter(active=True)쿼리 집합을 반환합니다.필터 방법을 추가할 수 있습니다.active_users.filter(is_deleted=False)

2. Q방법으로

from django.db.models import Q

not_deleted = User.objects.filter(Q(active=True) & Q(is_deleted=False)

복잡한 쿼리 세트를 보다 쉽게 관리할 수 있습니다.사용자를 필터링하려면 어떻게 해야 합니까?ID가 3이 아니라고요? Q를 간단하게 예를들면 됩니다.User.objects.filter(Q(active=True) & ~Q(id = 3))


당신의 말에 대한 답은.

Q를 사용하든 사용하지 않든, 이것은 동일한 원시 쿼리를 갖습니다.

SELECT ... FROM ... 
WHERE ("auth_user"."active" = True AND "auth_user"."is_deleted" = False)

데이터베이스 성능은 데이터를 추출하기 위해 데이터베이스를 얼마나 자주 두드리는지 또는 FK 관계를 통해 무언가를 추출할 때 '조인'과 같은 무거운 방법을 사용하는지와 관련이 있습니다.따라서 Q 또는 not을 사용해도 쿼리 문장이 같기 때문에 성능 차이가 나지 않습니다.

또한.

user = User.objects.filter(active=True)
not_deleted = User.objects.filter(active=True).filter(is_deleted=False)

user = User.objects.filter(active=True)
not_deleted = user.filter(is_deleted=False)

성능 차이를 주지 않을 것입니다.

쿼리 집합이 게으릅니다.user그리고.not_deleted변수에 쿼리 집합 문자열만 있습니다.위와 같이 변수를 정의할 때 데이터베이스에 바로 도달하지 않습니다.어쨌든 각 변수에 대해 세 번을 칠 것입니다.

최선의 방법은 다음과 같습니다.

active_users = User.objects.filter(active=True)
not_deleted = active_users.filter(is_deleted=False)
deleted = active_users.filter(is_deleted=True)

그래서 제가 제대로 이해했다면, 당신의 질문에 대한 답은 '네'일 수도 있습니다.

Queryset을 원하는 시간만큼 필터링할 수 있습니다.filter()새 쿼리 세트를 반환하므로 필터링 후 쿼리 세트가 필터링되고 새 쿼리 세트를 반환하는 다른 메서드 및 다른 메서드를 기준으로 필터링 또는 순서 지정할 수 있습니다.

따라서 다음을 수행할 수 있습니다.

active = User.objects.filter(active=True)
deleted = active.filter(is_deleted=True)
not_deleted = active.filter(is_deleted=False)

그 모든 것은User.objects이고 -는 Queryset입니다.User.objects.filter또한 쿼리 집합을 반환합니다.

언급URL : https://stackoverflow.com/questions/45228187/possible-to-filter-the-queryset-after-querying-django

반응형