在 Django ORM 中,"values" 和 "annotate" 无法分组
In Django ORM, "values" and "annotate" are not working to group by
我有一个 table 这样的:
现在我想总结一下每次约会的饭菜。我已经写了下面的代码。但是它并没有像我想要的那样工作。
型号:
class Meal(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
date_of_meal = models.DateField()
morning_meal = models.SmallIntegerField(default=0)
mid_day_meal = models.SmallIntegerField(default=0)
night_meal = models.SmallIntegerField(default=0)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
class Meta:
ordering = ['-updated', '-timestamp']
def __str__(self):
return str(self.date_of_meal)
代码:
meals_list = Meal.objects.values('date_of_meal').annotate(mm=Sum('morning_meal'), mdm=Sum('mid_day_meal'), nm=Sum('night_meal'))
输出:
<QuerySet [{'mdm': 0, 'mm': 1, 'date_of_meal': datetime.date(2017, 3,
23), 'nm':
1}, {'mdm': 1, 'mm': 1, 'date_of_meal': datetime.date(2017, 3, 23), 'nm': 0}, {
'mdm': 1, 'mm': 0, 'date_of_meal': datetime.date(2017, 3, 22), 'nm': 1}, {'mdm':
0, 'mm': 1, 'date_of_meal': datetime.date(2017, 3, 22), 'nm': 1}, {'mdm': 1, 'm
m': 1, 'date_of_meal': datetime.date(2017, 3, 21), 'nm': 1}, {'mdm': 1, 'mm': 1,
'date_of_meal': datetime.date(2017, 3, 21), 'nm': 1}, {'mdm': 1, 'mm': 1, 'date
_of_meal': datetime.date(2017, 3, 20), 'nm': 1}, {'mdm': 1, 'mm': 1, 'date_of_me
al': datetime.date(2017, 3, 20), 'nm': 1}, {'mdm': 1, 'mm': 0, 'date_of_meal': d
atetime.date(2017, 3, 19), 'nm': 0}, {'mdm': 0, 'mm': 0, 'date_of_meal': datetim
e.date(2017, 3, 19), 'nm': 1}]>
它多次重复相同的日期。
但我想要这样:
<QuerySet [{'mdm': 1, 'mm': 2, 'date_of_meal': datetime.date(2017, 3, 23), 'nm':
1},
{'mdm': 1, 'mm': 1, 'date_of_meal': datetime.date(2017, 3, 22), 'nm': 2},
............
............
so on........
]>
如何获得预期的输出?
(答案隐藏在评论中,所以我把它变成了一个正确的答案。我花了几个小时来解决同样的问题。)
关键问题是 Django 会自动将您排序的字段添加到 values()
。所以在你的情况下,你认为你正在做.values('date_of_meal')
。但是由于模型上的 ordering = ['-updated', '-timestamp']
,django 将它变成了 `.values('date_of_meal', 'updated', 'timestamp') 而不是...
有了这样一个意想不到的 .values()
你当然不会得到你期望的 group_by 行为。
解决方案是 "reset" 默认排序,方法是添加一个空的 .order_by()
或者,在您的情况下,添加 .order_by('date_of_meal')
.
我有一个 table 这样的:
现在我想总结一下每次约会的饭菜。我已经写了下面的代码。但是它并没有像我想要的那样工作。
型号:
class Meal(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
date_of_meal = models.DateField()
morning_meal = models.SmallIntegerField(default=0)
mid_day_meal = models.SmallIntegerField(default=0)
night_meal = models.SmallIntegerField(default=0)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
class Meta:
ordering = ['-updated', '-timestamp']
def __str__(self):
return str(self.date_of_meal)
代码:
meals_list = Meal.objects.values('date_of_meal').annotate(mm=Sum('morning_meal'), mdm=Sum('mid_day_meal'), nm=Sum('night_meal'))
输出:
<QuerySet [{'mdm': 0, 'mm': 1, 'date_of_meal': datetime.date(2017, 3,
23), 'nm':
1}, {'mdm': 1, 'mm': 1, 'date_of_meal': datetime.date(2017, 3, 23), 'nm': 0}, {
'mdm': 1, 'mm': 0, 'date_of_meal': datetime.date(2017, 3, 22), 'nm': 1}, {'mdm':
0, 'mm': 1, 'date_of_meal': datetime.date(2017, 3, 22), 'nm': 1}, {'mdm': 1, 'm
m': 1, 'date_of_meal': datetime.date(2017, 3, 21), 'nm': 1}, {'mdm': 1, 'mm': 1,
'date_of_meal': datetime.date(2017, 3, 21), 'nm': 1}, {'mdm': 1, 'mm': 1, 'date
_of_meal': datetime.date(2017, 3, 20), 'nm': 1}, {'mdm': 1, 'mm': 1, 'date_of_me
al': datetime.date(2017, 3, 20), 'nm': 1}, {'mdm': 1, 'mm': 0, 'date_of_meal': d
atetime.date(2017, 3, 19), 'nm': 0}, {'mdm': 0, 'mm': 0, 'date_of_meal': datetim
e.date(2017, 3, 19), 'nm': 1}]>
它多次重复相同的日期。
但我想要这样:
<QuerySet [{'mdm': 1, 'mm': 2, 'date_of_meal': datetime.date(2017, 3, 23), 'nm':
1},
{'mdm': 1, 'mm': 1, 'date_of_meal': datetime.date(2017, 3, 22), 'nm': 2},
............
............
so on........
]>
如何获得预期的输出?
(答案隐藏在评论中,所以我把它变成了一个正确的答案。我花了几个小时来解决同样的问题。)
关键问题是 Django 会自动将您排序的字段添加到 values()
。所以在你的情况下,你认为你正在做.values('date_of_meal')
。但是由于模型上的 ordering = ['-updated', '-timestamp']
,django 将它变成了 `.values('date_of_meal', 'updated', 'timestamp') 而不是...
有了这样一个意想不到的 .values()
你当然不会得到你期望的 group_by 行为。
解决方案是 "reset" 默认排序,方法是添加一个空的 .order_by()
或者,在您的情况下,添加 .order_by('date_of_meal')
.