检测Django Rest Framework

时间:2017-07-29 18:04:55

标签: python django django-models django-rest-framework

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

2 个答案:

答案 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.itemsproductPurchase的数量。

但是,您可能希望以不同的方式执行此操作,例如汇总产品的所有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)