Django 使用子查询对查询集进行分组

时间:2021-01-05 17:40:48

标签: django

我正在尝试在 Django 中创建一个分组查询集,首先按 occupation 分组,然后按 occupation 聚合 date_rented 的总和,其中 date_rented 按月分组。

我已经能够在 python 中获得所需的结果,但对我来说似乎效率很低,因为需要为每个 occupation 执行子查询以根据 date_rented 获得总和。无法使用 Django 的内置查询 API,我想我别无选择,只能使用这个解决方案,但如果有人能帮助我使用 Django 内置查询 API 解决这个问题,我将永远感激。

模型

class Tenant(models.Model):
    name = models.CharField(max_lenght=254)
    occupation = models.CharField(max_length=254)
    date_rented = models.DateField()

示例数据

| id | name              | occupation         | date_rented   |
| -- | ----------------- | ------------------ | ------------- |
| 1  | Orlando Barrero   | Electrician        | 2020-01-13    |
| 2  | Miguel Espinosa   | Mechanic           | 2020-01-24    |
| 3  | Renan Figueroa    | Electrician        | 2020-02-22    |
| 4  | Marco Galvez      | Mechanic           | 2020-03-13    |
| 5  | Eric Mendosa      | Mechanic           | 2020-03-22    |
| 6  | Giovani Vela      | Electrician        | 2020-03-24    |

预期结果

| occupation         | January | February | March |
| ------------------ | ------- | -------- | ----- |
| Electrician        | 1       | 1        | 1     |
| Mechanic           | 1       | 0        | 2     |

1 个答案:

答案 0 :(得分:0)

您可以通过以下方式获取每个职业和每月的元素:

from django.db.models import Count
from django.db.models.functions import TruncMonth

Tenant.objects.values(
    'occupation',
    month=TruncMonth('date_rented')
).annotate(
    count=Count('pk')
).order_by('occupation', 'month')

这将返回一个查询集:

<QuerySet [
    {'occupation': 'Electrician', 'month': date(2020, 1, 1), 'count': 1},
    {'occupation': 'Electrician', 'month': date(2020, 2, 1), 'count': 1},
    {'occupation': 'Electrician', 'month': date(2020, 3, 1), 'count': 1},
    {'occupation': 'Mechanic', 'month': date(2020, 1, 1), 'count': 1},
    {'occupation': 'Mechanic', 'month': date(2020, 3, 1), 'count': 2},
]>

但是,您仍然需要对数据进行后处理。此外,没有 Tenant 对象的月份/职业组合将列在查询集中,例如 Mechanic/February is here not > 现在。