Yes, you can reuse existing querysets.
everyone = User.objects.filter(is_active=True)
active_not_deleted = everyone.filter(is_deleted=False)
active_is_deleted = everyone.filter(is_deleted=True)
This is not really making anything faster though, in fact, this code block won’t even execute a query against the database because Django QuerySets are lazily evaluated. What I means is that it won’t send the query to the database until you actually need the values. Here’s an example that will talk to the database.
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)
Recommend reading:
- 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
As an addition to this answer, you could make a single query and then filter in Python if you really wanted. Mind you, you could not do subsequent filtering on the lists because they are not QuerySets.
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))
In this last example, everyone is a queryset, and active_not_deleted and active_is_deleted are Python lists of User objects. The everyone queryset will only be evaluated once in the first list(everyone) call, and then the results are cached.