はい、既存のクエリセットを再利用できます。
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)
読むことをお勧めします:
- https://docs.djangoproject .com / en / 1.11 / topics / db / queries /#querysets-are-lazy
- https://docs.djangoproject.com/en /1.11/ref/models/querysets/#iterator
- https://docs.djangoproject .com / en / 1.11 / topics / db / queries /#caching-and-querysets
この回答に加えて、本当に必要な場合は、単一のクエリを作成してからPythonでフィルタリングすることができます。リストはQuerySetではないため、リストに対して後続のフィルタリングを実行できませんでした。
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
UserオブジェクトのPythonリストです。 everyone
クエリセットは、最初のlist(everyone)
で1回だけ評価されます を呼び出すと、結果がキャッシュされます。