2011-03-10 24 views
1

我是Django Annotations的新手,我试图在给定位置生成订单收入摘要报告。Django Annoation:从Annoation值获取对象而不是ID

例如,该报告将是这个样子:

Location Name | Location Type | Sum of Order Subtotal 

而这些是我会用模型示例:

class Order(models.Model): 
    order_subtotal = models.DecimalField(...) 
    location = models.ForignKey('Location') 
    .... 

class Location(models.Model): 
    name = models.CharField(...) 
    type = models.IntegerField(...) 
    .... 

我能够运行一些查询注释。 ..

from django.db import models 

In [1]: order_locations =\ 
    Order.objects.values('location').annotate(models.Sum('order_subtotal')) 

In [2]: order_locations[0] 
Out[2]: {'location': 1, 'order_subtotal__sum': Decimal('1768.08')} 

In [3]: location = order_locations[0]['location'] 

In [4]: location 
Out[4]: 1 

In [5]: type(location) 
Out[5]: <type 'int'> 

但是,上面的行返回一个int而不是一个Location对象。我希望能够以某种方式引用位置名称和位置类型,如location.name或location.type。有没有办法在注解中返回一个位置对象,而不是只有位置ID(需要单独的潜在昂贵的查找)?

任何意见是非常感谢。

谢谢, 乔

回答

2

计算的order_subtotal为每个位置总和:为每个位置类型的order_subtotal

>>> locations = Location.objects.all().annotate(total=Sum('order__order_subtotal')) 
>>> [(loc.name, loc.typ, loc.total) for loc in locations] 
[(u'A', 1, Decimal('10.00')), 
(u'B', 1, Decimal('20.00')), 
...] 

计算总和:

>>> Location.objects.all().values('type').annotate(total=Sum('order__order_subtotal')) 
[{'total': Decimal('70.00'), 'typ': 1}, {'total': Decimal('179.00'), 'typ': 2}] 

计算总和为每个位置,但不包括14天以上的订单::

>>> starting_date = datetime.datetime.now() - datetime.timedelta(14) 
>>> locations = Location.objects.filter(order__date_gte=starting_date) \ 
           .annotate(total=Sum('order__order_subtotal')) 

还请注意:ORDER OF annotate() AND filter() CLAUSES在django文档。

+0

很漂亮,谢谢! – 2011-03-10 18:09:52

+0

一个相关的问题。有没有一种方法可以将过滤器放在作为注释一部分进行汇总的订单上?我知道我的例子不是那么详细,但是想知道是否有方法在订单日期过滤。 – 2011-03-10 18:20:34

+1

是的,你可以把过滤器,我已经更新了我的答案。 – Ski 2011-03-10 18:32:40

相关问题