Reputation: 1607
When chaining filters in Django, what is the most efficient way of counting the resulting records from an individual filter? Without running the filter twice that is.
i.e.
results = my_model.objects.all()
for filter in my_filters:
results = results.filter(filter.get_filter_string())
individual_num_records_affected = my_model.objects.filter(filter.get_filter_string())
Upvotes: 0
Views: 483
Reputation: 47866
Since you just need the number of results at each step, its more efficient to use .count()
on the querysets.
From the querysets
documentation:
Note: If you only need to determine the number of records in the set (and don’t need the actual objects), it’s much more efficient to handle a count at the database level using SQL’s
SELECT COUNT(*)
. Django provides acount()
method for precisely this reason.
You should not use .len()
as it will load all of the record into Python objects and calls len()
on the result which you don't need. You just need the number of records and .count()
would be the better option.
Also, remember that querysets are evaluated lazy.
Internally, a QuerySet can be constructed, filtered, sliced, and generally passed around without actually hitting the database. No database activity actually occurs until you do something to evaluate the queryset.
So, until you try to use the results of the queryset, the queryset will not be evaluated i.e. no database hit will occur.
The statement results = results.filter(filter.get_filter_string())
will not hit the database until you try to use the results
. You can do .filter()
on a queryset multiple times but until you don't use it, there would be no database hit.
Upvotes: 3