聚合Django

时间:2018-06-10 20:20:41

标签: django django-queryset django-database

假设以下示例模型:

# models.py
class event(models.Model):
    location = models.CharField(max_length=10)
    type = models.CharField(max_length=10)
    date = models.DateTimeField()
    attendance = models.IntegerField()

我希望使用Django ORM获取每个活动地点和类型组合的最新日期的出勤人数。根据{{​​3}},我们可以使用values之前的annotation来实现与此接近的目标。

  

...原始结果根据values()子句中指定的字段的唯一组合进行分组。然后为每个唯一组提供注释;注释是在该组的所有成员上计算的。

因此,使用示例模型,我们可以写:

event.objects.values('location', 'type').annotate(latest_date=Max('date'))

确实按位置和类型对事件进行分组,但不会返回attendance字段,这是所需的行为。

我尝试的另一种方法是使用不同的,即:

event.objects.distinct('location', 'type').annotate(latest_date=Max('date'))

但是我收到了错误

NotImplementedError: annotate() + distinct(fields) is not implemented.

我找到了一些依赖于Django数据库特定功能的答案,但我想找到一个与底层关系数据库无关的解决方案。

1 个答案:

答案 0 :(得分:0)

好吧,我认为这个可能真的适合你。它基于一个假设,我认为这是正确的。

创建模型对象时,它们都应该是唯一的。您在同一event的同一date内同一location上有两个type似乎不大可能。因此,假设开始:(作为格式化注释,类Names倾向于以大写字母开头,以区分classesvariablesinstances。)

# First you get your desired events with your criteria.
results = Event.objects.values('location', 'type').annotate(latest_date=Max('date'))

# Make an empty 'list' to store the values you want.
results_list = []

# Then iterate through your 'results' looking up objects
# you want and populating the list.
for r in results:
    result = Event.objects.get(location=r['location'], type=r['type'], date=r['latest_date'])
    results_list.append(result)

# Now you have a list of objects that you can do whatever you want with.

您可能需要查找Max(Date)的确切输出,但这应该会让您走上正确的道路。