Reputation: 3286
I have pizzas and I have toppings.
class Pizza(ModelBase):
name = models.CharField(max_length=255)
toppings = models.ManyToManyField('Topping', blank=True, related_name='pizzas')
class Topping(ModelBase):
name = models.CharField(max_length=255)
Let's suppose I want to add the toppings Tomato
and Cheese
to every pizza in my database.
At the moment I can do it with a nasty for loop:
toppings = Toppings.objects.filter(Q(name='Tomato') | Q(name='Cheese'))
for pizza in Pizza.objects.all():
pizza.toppings.add(*toppings)
Is there a way to achieve the same thing without having to loop all the pizzas? Maybe using the through table that Django creates?
I know that I can delete the toppings from all the pizzas using the following query:
Pizza.toppings.through.objects.filter(topping__in=toppings).delete()
but I haven't been able to add toppings to multiple pizzas without the for loop.
Upvotes: 0
Views: 125
Reputation: 15738
You could use .set() from reverse relation to set for each topping all pizzas as already mentioned in comment or you could do bulk_create through table entries
Something in a line of following:
topping_ids = Toppings.objects.filter(
Q(name='Tomato') | Q(name='Cheese')
).values_list('id', flat=True)
pizza_ids= Pizza.objects.values_list('id', flat=True)
through_objects = [Pizza.toppings.through(topping_id=entry[0],
pizza_id=entry[1]) for entry in
itertools.product(topping_ids, pizza_ids)]
Pizza.toppings.through.objects.bulk_create(through_objects)
Upvotes: 2