在Django Rest Fram中检测相关模型的变化

2024-04-20 11:03:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我在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)

Tags: 项目用户falsedefault产品modelsitemsproduct
2条回答

简单的方法是重写保存、删除方法或使用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)

使用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.itemsPurchaseproduct的数目。你知道吗

不过,您可能需要做一些不同的操作,比如聚合产品的所有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'])

相关问题 更多 >