2012-11-18 36 views
2

考虑以下型号的最新资料:有效地选择不同类别

class Data(Model): 
     created_at = models.DateTimeField() 
     category = models.CharField(max_length=7) 

我想选择所有类别的最新对象。

this question,我选择了不同的类别,然后制作一个单独的查询为他们每个人:

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为不同的类别,然后对每个类别单独查询)。

有没有办法用单个查询来做到这一点?

+0

如果你不打算有一个分离的类别模型,你可以将Data.objects.all()分配给一个变量并运行一个函数来检索每个类别的最新数据,这只是一个查询 –

+0

顺便说一句,缩短你的当前代码使用一个单独的分类模型: '最新的obj = obj.data_set.latest()为obj在Category.objects.all()如果obj.data_set.count()]' –

回答

0

通常,您可以在关系数据库中使用组。 Django的有aggergation 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()子句到查询的末尾,但是这不会为结果集添加额外的列。