我在django中有一个模型,让我们称之为product
,由多个purchase
实例引用。
可以对product
的任意数量的商品进行购买,但需遵守以下约束条件:
给定产品的所有购买中的所有商品总数必须小于设定的最大商品数,每种商品的定义不同。
用户可以为产品创建purchase
,并且我希望在任何给定时间跟踪所有购买所涵盖的商品总数。
由于用户可以修改或删除他们的purchase
,从而更改购买的商品总数,这一点很复杂。
我如何跟踪每个product
的这个数字,并在每次purchase
更改时更新?是否有可以收听product
购买并检测到更改的挂钩?
purchase
型号:
class Purchase(models.Model):
items = models.IntegerField(blank=False, default=1)
delivery_method = models.CharField(max_length=100, blank=False, default='')
#...
product = models.ForeignKey('product.Product',
related_name='purchases', on_delete=models.CASCADE)
product
型号:
class Product(models.Model):
name = models.CharField(max_length=100, blank=False,)
items_offered = models.IntegerField(blank=False, default=2)
# Items purchased should be the total number
# of items in all purchases for this product...
# How do I keep it updated?
items_purchased = models.IntegerField(blank=False, default=0)
答案 0 :(得分:1)
使用post_save
信号。
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=Purchase)
def update_purchase_amounts(sender, instance, created, **kwargs):
product = Product.objects.get(id=instance.product.id)
product.items_purchased += instance.items
product.save(update_fields=['items_purchased'])
我假设purchase.items
是product
中Purchase
的数量。
但是,您可能希望以不同的方式执行此操作,例如汇总产品的所有Purchase.items
字段,这样您就不会在每次保存Purchase
实例时不断更新购买的金额。所以也许可以使用类似的东西:
from django.db.models.aggregates import Sum
counts = Purchase.objects.filter(product=instance.id).aggregate(Sum('items'))
product.items_purchased = counts
product.save(update_fields=['items_purchased'])
答案 1 :(得分:1)
简单方法是覆盖保存,删除方法或使用django signals:
class Purchase(models.Model):
# ... model definition
def update_items_purchased(self, product):
purchases = Purchase.objects.filter(product=product)
if purchases:
total = purchases.aggregate(total=Sum('items')).get('total', 0)
else:
total = 0
product.items_purchased = total
product.save()
def save(self, *args, **kwargs):
super(Purchase, self).save(*args, **kwargs)
self.update_items_purchased(self.product)
def delete(self, *args, **kwargs):
super(Purchase, self).delete(*args, **kwargs)
self.update_items_purchased(self.product)