I’m a beginner, I discover many things and sometimes I feel overwhelmed about all the informations and tricks to learn.
I try to do a django project for a pizzeria. People can order pizza online, the order is simple : you can choose one or more pizza and optionally add some Extras (adding cheese, ham or whatever…) for each pizza you ordered and it’s added to the cart.
My problem is to calculate automatically the price for each pizza.
Basically here’s my Model file:
class Pizza(models.Model):
nom = models.CharField(max_length=30)
ingrédients = models.CharField(max_length=500)
prix = models.DecimalField(max_digits=4, decimal_places=2)
nom means name
class Extra(models.Model):
sup = models.CharField(max_length=30)
prix = models.DecimalField(max_digits=3, decimal_places=2)
sup is the name of the extra.
class IndividualChoice(models.Model):
pizzaChosen = models.ForeignKey(‘Pizza’, default="", null=True, on_delete=models.CASCADE)
extraChosen = models.ManyToManyField(‘Extra’, blank=True)
panier = models.ForeignKey(‘Cart’, default="", on_delete=models.CASCADE)
calzone = models.BooleanField(default=False)
prix = models.DecimalField(max_digits=5, decimal_places=2, default=0)
IndividualChoice is a bit weird. It’s a model which stores each choice, here “panier” means Cart which has a model but I don’t think it’s useful to make it appear here.
I learned a bit about django signals, so I tried to create one:
def prix_extra_calcul(sender, instance, action, *args, **kwargs):
instance.prix = 0
if action == “post_add” or action == “post_remove” or action == “post_clear”:
for extra in instance.extraChosen.all():
instance.prix += extra.prix
instance.prix += instance.pizzaChosen.prix
instance.save()
m2m_changed.connect(prix_extra_calcul, sender=IndividualChoice.extraChosen.through)
It works well when I create a pizza with extra but if only change the pizza the m2m signal won’t be fired. So I tried to find another solution but it’s stupid:
def prix_pizza_calcul(sender, instance, *args, **kwargs):
instance.prix = 0
for extra in instance.extraChosen.all():
instance.prix += extra.prix
instance.prix += instance.pizzaChosen.prix
def prix_extra_calcul(sender, instance, action, *args, **kwargs):
if action == “post_add” or action == “post_remove” or action == “post_clear”:
# no need to write code because prix_pizza_calcul will be fired by instance.save()
instance.save()
pre_save.connect(prix_pizza_calcul, sender=IndividualChoice)
m2m_changed.connect(prix_extra_calcul, sender=IndividualChoice.extraChosen.through)
The second solution "works well" when I want to modify a choice but when I create a new pizza I have this error message “maximum recursion depth exceeded while calling a Python object”. And I think it’s because i’m looping over something not saved.
I’m completely stuck with this problem, I tried to solve it for several days. Should I create a Signal, is a signal is appropriate for this kind of problem ?
(What a loooong way to be a web developer…)
Thanks for reading !