Let's say I query Workplace
s in a City
and prefetch all their Worker
s, which is a many-to-many relationship:
workplaces = list(city.workerplace_set.filter(num_employees__lte=350).prefetch_related('Worker'))
If I use any QuerySet
operation on Worker
s from any of the Workplace
s, will the database be hit or not? I could not make out a clear answer from the docs.
workplaces_with_interns = [workplace for workplace in workplaces
# is this filter going to query the database?
if workplace.worker_set.filter(salary=0).exists()]
PS: someone is probably going to point out that I can reach the same answer by simply making a query for city.workerplace_set
instead of making it a list
. Yes, I know, but that is not possible because I am caching the workplaces
so that the database is not hit every time the function that does all this is called.
Yes. This will hit the database because you are running a specific query - exists on a filter - that was not present in the original prefetch.
In your case, since you already have the workers, it would be better to filter them in Python:
[workplace for workplace in workplaces
if any(w.salary == 0 for w in workplace.worker_set.all())]
Alternatively, if this is the only reason you need the prefetch, you could use a Prefetch object in the original query to only fetch the workers with 0 salary.
(Just noticed you are using 1.4, which doesn't have Prefetch objects. You should definitely upgrade; not only for that reason, but mainly because 1.4 is very old and unsupported, and is therefore certainly a security risk.)