I have a relatively complex model structure in a django project (v2.1.4). Let's say:
class Pizza(models.Model):
pass
class ToppingPlacedOnPizza(models.Model):
# Breaks a many-to-many relationship between Pizza and Topping and stores specific data
# like the position of the topping in the pizza
pizza = models.ForeignKey(Pizza, related_name='placed_toppings')
topping = models.ForeignKey(Topping)
# position ...
class Topping(models.Model):
brand = models.ForeignKey(Brand)
class Brand(models.Model):
name = models.CharField(max_length=32)
I need to retrieve all the names of the brands that make toppings for each pizza of a set of pizzas. Say:
pizza1: brand1, brand2, brand3
pizza2: brand2, brand4
...
To do so, prefetch_related has been of great help in order to improve performance:
pizzas.prefetch_related('placed_toppings__topping__brand')
But when making a query for ~1000 pizzas it starts being really slow.
According to this stackoverflow answer, using Prefetch class and to_attr could improve performance, but I couldn't make it work on my case. It's not clear in which object to_attr will write the new attribute because of the nested lookup.
I made to_attr work on first level. When setting pizzas.prefetch_related(Prefetch('placed_toppings', to_attr('mytoppings'))), then pizzas[0].mytoppings exists.
But when setting pizzas.prefetch_related(Prefetch('placed_toppings__topping__brand', to_attr('mybrands'))), none of the following exist:
pizzas.mybrands
pizzas[0].mybrands
pizzas[0].placed_toppings.mybrands
pizzas[0].placed_toppings.first().mybrands
pizzas[0].placed_toppings.first().topping.mybrands
Any ideas on how to improve performance or make to_attr work on nested lookups?