考虑以下模型:
class Data(Model):
created_at = models.DateTimeField()
category = models.CharField(max_length=7)
我想为所有类别选择最新的对象。
在这个问题之后,我将选择不同的类别,然后为每个类别进行单独的查询:
categories = Data.objects.distinct('category').values_list('category', flat=True)
for category in categories:
latest_obj = Data.objects.filter(category=category).latest('created_at')
该方法的缺点是它进行大量查询(1 个用于不同类别,然后每个类别一个单独的查询)。
有没有办法用单个查询来做到这一点?
通常,您将在关系数据库中使用组依据。Django 有一个聚合 API(https://docs.djangoproject.com/en/dev/topics/db/aggregation/#aggregation),允许您执行以下操作:
from django.db.models import Max
Data.objects.values('category').annotate(latest=Max('created_at'))
这将执行单个查询并返回如下列表:
[{'category' : 'cat1', 'latest' : '01/01/01' },{'category' : 'cat2' 'latest' : '02/02/02' }]
但我想您可能还想在此列表中检索数据记录 ID。在这种情况下,Django 不会让你思考变得简单。问题是 django 使用 value 子句中的所有字段进行分组,并且您无法从查询中返回额外的列。
编辑:我最初建议在基于 Web 资源的查询末尾添加第二个 values() 子句,但这不会向结果集添加额外的列。