我是一个初学者,我发现很多东西,有时我对所有的信息和学习技巧不知所措。
我尝试为比萨店做一个django项目。人们可以在线订购披萨,订单很简单:您可以选择一个或多个披萨,还可以为您订购的每个披萨添加一些附加功能(添加奶酪,火腿或其他东西),然后将其添加到购物车中。
我的问题是自动计算每个披萨的价格。
基本上是我的模型文件:
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表示名称
class Extra(models.Model):
sup = models.CharField(max_length=30)
prix = models.DecimalField(max_digits=3, decimal_places=2)
sup是多余的名称。
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有点奇怪。这是一个存储每个选项的模型,这里的“ panier”表示具有模型的购物车,但我认为将其显示在这里不是有用的。
我了解了一些有关Django信号的知识,所以我尝试创建一个:
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)
当我创建一个额外的披萨时效果很好,但是如果仅更改披萨,则不会触发m2m信号。所以我试图找到另一种解决方案,但这很愚蠢:
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)
第二个解决方案在我要修改选择时有效,但是当我创建一个新的披萨时,我收到此错误消息:“调用Python对象时,超出了最大递归深度”。我认为这是因为我正在遍历未保存的内容。
我完全解决了这个问题,我尝试解决了好几天。我应该创建一个信号,信号是否适合此类问题?
((成为Web开发人员的一种非常轻松的方式…)
感谢阅读!
也许您可以尝试使用@receiver装饰器。每个post_save都会发出一个信号。
from django.dispatch import receiver
@receiver(post_save, sender=IndividualChoice)
def prix_extra_calcul(sender, instance, created, **kwargs):
...