Django获取每个组的最新信息,按外键分组

use*_*803 5 django group-by count

假设我有类似以下模型的东西:

class Product(models.Model):
  name = models.CharField(max_length=50)

class Sale(models.Model):
  product = models.ForeignKey(Product)
  sale_date = models.DateField()
Run Code Online (Sandbox Code Playgroud)

我想获得每种产品的最新销售。最新是指最新的销售日期。另外,在同一查询中,我想获取每种产品的销售数量。

用SQL术语,我需要按product_id分组,以计算每种产品的销售数量(这是每个组的长度)。也许还可以按日期(在每个组中)订购以仅获得最新的产品销售。

使用django ORM,我意识到我需要以某种方式使用annotate(),或者可能与结合使用values()。但是我仍然不知道怎么做。

假设我有此产品表:

| id |   name    |    
===================
| 1  | Book      |  
| 2  | Telephone |
Run Code Online (Sandbox Code Playgroud)

和这个销售表:

| id | product_id | sale_date |
=================================
| 1  |      1     | 05-02-2015 |
| 2  |      2     | 04-02-2015 |
| 3  |      2     | 03-02-2015 |
| 4  |      1     | 06-02-2015 |
| 5  |      1     | 01-02-2015 |
Run Code Online (Sandbox Code Playgroud)

我想得到像这样的输出:

| product_id |    name   | sale_date  | num_sales |
====================================================
|     1      | Book      | 06-02-2015 |     3     |
|     2      | Telephone | 04-02-2015 |     2     |
Run Code Online (Sandbox Code Playgroud)

由于2015年6月2日是product_id = 1(书籍)的最新销售日期,而2015年4月2日是product_id = 2(电话)的最新销售日期。

Two*_*ist 1

from django.db.models import Count, Max
query = Product.objects.annotate(num_sales=Count('sale'))
query = query.annotate(latest_sale_date=Max('sale__sale_date'))
for prod in query.all():
    print (prod.pk, prod.name, prod.latest_sale_date, prod.num_sales)
Run Code Online (Sandbox Code Playgroud)

您将得到如下输出:

(1, u'Book', datetime.date(2015, 6, 2), 3)
(2, u'Telephone', datetime.date(2015, 4, 2), 2)
Run Code Online (Sandbox Code Playgroud)

类似于您在问题中的预期输出。请注意,您传递给注释的任何 kwarg 都会成为查询结果的属性。