开发者

Django Annoation: Getting Object from Annoation Values Rather than ID

开发者 https://www.devze.com 2023-02-16 05:31 出处:网络
I\'m new to Django Annotations and I\'m trying to generate a summary report of Order income at given Locations.

I'm new to Django Annotations and I'm trying to generate a summary report of Order income at given Locations.

For example, the report would look something like this:

Location Name | Location Type | Sum of Order Subtotal 

And these are example models that I would use:

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

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

I'm able to run some queries to annotate...

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'>

However, the line above returns an int rather than a Location object. I'd like to be able to somehow reference the location name and location type like locati开发者_如何学Con.name or location.type. Is there some way to return a location object in the annotation rather than only the location id (requiring separate potentially expensive lookups)?

Any advice is much appreciated.

Thanks, Joe


Calculate sum of order_subtotal for each location:

>>> 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')),
 ...]

Calculate sum of order_subtotal for each location type:

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

Calculate sum for each location, but don't include orders older than 14 days::

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

Also give some attention to: ORDER OF annotate() AND filter() CLAUSES at django docs.

0

精彩评论

暂无评论...
验证码 换一张
取 消