Django“额外”查询

时间:2012-06-05 19:01:37

标签: python sql django

我的models.py中有以下模型结构,包含Items和Offers:

class Item(models.Model):

    STATUS_CHOICES = (
        ('A', 'Active'),
        ('C', 'Cancelled'),
    ) 

    status = models.CharField(max_length=11, choices=STATUS_CHOICES)
    target_amount = models.PositiveIntegerField()
    ...

class Offer(models.Model)

    STATUS_CHOICES = (
        ('A', 'Active'),
        ('C', 'Cancelled'),
    ) 

    status = models.CharField(max_length=11, choices=STATUS_CHOICES)
    amount = models.PositiveIntegerField()
    item = models.ForeignKey(Item)
    ...

我想在views.py中编写一个查询,以获取每个项目的以下内容:

  1. 此商品的当前(有效)商品总数
  2. 此商品的优惠所满足的目标百分比(即[总数来自(1)] / target_amount * 100)
  3. 我一直试图用“额外”来实现这个目标(使用postgres):

    items = Item.objects.filter(status='A').extra(
        select={
            'total_amount' : 'select coalesce(sum(amount),0) from myapp_offer where myapp_offer.item_id = myapp_item.id and myapp_offer.status = \'A\'',
            'percentage_met' : '(((select coalesce(sum(amount),0) from myapp_offer where myapp_offer.item_id = myapp_item.id and myapp_offer.status = \'A\') / target_amount) * 100)'
        }
    )
    

    现在第一个选择(total_amount)正常工作并返回我期望的内容,但percentage_met始终为0.任何人都可以帮我解释原因吗?

    编辑:应该提到我希望能够通过percentage_met

    订购

2 个答案:

答案 0 :(得分:1)

您不需要extra。只需使用aggregation

from django.db.models import Sum

items = Item.objects.filter(status='A').annotate(total_amount=Sum('offer__amount'))
无论如何,

percentage_met是每个对象,所以这只是你模型上的一个方法:

class Item(models.Model):
    ...
    @property
    def percentage_met(self):
        if hasattr(self, 'total_amount'):
            return (self.total_amount / float(self.target_amount)) * 100
        return None

答案 1 :(得分:1)

我不认为上面的代码是获取所需值的最简洁方法,但是,假设它是 - 我怀疑你看到的问题实际上是SQL中的划分问题 - 一个int / int被覆盖到最近的int,在这种情况下为零。 Sum肯定是一个int;什么是target_amount,它来自哪里?是int吗?

在Postgres中:

select 2/100; 
?column? 
----------
        0
(1 row)

如果是,请投射其中一个值:

select 2::numeric/100;
?column?        
------------------------
 0.02000000000000000000
(1 row)