|Reported by:||g00fy||Owned by:||nobody|
|Component:||Database layer (models, ORM)||Version:||master|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
I suggest, that prefetch_related should be lazy. What I mean is, it would only execute aditional query, when related model needs to be accessed.
# this would do just one query - prefetch_related is lazy pizzas = Pizza.objects.all().prefetch_related('toppigns') for pizza in pizzas: print pizza.name
# Proposal A # now we want to access the related objects, # 1 aditional query (intermediate m2m table) is executed # not 2 since, we only need the id of the related object (which is already in the m2m table) # the 2nd query would result in a set of 'lazy' objects for pizza in pizzas: for topping in pizza.toppings.all(): print topping.id # now 3rd query is made for pizza in pizzas: for topping in pizza.toppings.all(): print topping.name
# Proposal B # 2nd query is made (with the current implementation - m2m table join) for pizza in pizzas: for topping in pizza.toppings.all(): print topping.id
let's consider logic like this:
pizzas = Pizza.objects.all() print len(pizzas) if pizzas.name == 'pepperoni': for pizza in pizzas: print [topping.name for topping in pizza.toppings.all()] else: for pizza in pizzas: print pizza.name
in otherwords, this would be useful, if there is some complex logic that sometimes may require prefetch_related (and this requirement can be only checked after the query was made - so there is no way to do the checking & then doing prefetch_related).