python - 按日期对记录进行分组并添加字段列表

标签 python django django-models django-queryset django-orm

我有以下模型:

class Book(models.Model):
    name = models.CharField(max_length=255)
    published = models.DateField()
    items_sold = models.IntegerField()

现在,我想按出版日期对所有图书进行分组,并对已售商品 (items_sold) 进行SUM。此外,我想将所有名称的列表添加到输出中。所以我的预期输出将如下所示:

[{'date': datetime.date(2015, 12, 14), 'total_sold': 5000, 'names': ['Book A', 'Book B']}, 
 {'date': datetime.date(2016, 11, 4), 'total_sold': 10000, 'names': ['Book C']}, ... ]

我尝试使用annotate解决这个问题:

Book.objects.values('date').annotate(total_sold=Sum('items_sold'))

但我不知道如何将名称列表放入结果中。 annotate 是正确的方法吗?有谁知道如何解决这个问题吗?

编辑:

感谢 Todor 的评论,我找到了使用自定义聚合的部分解决方案:

class Concat(models.Aggregate):
    """
    Using SQLite `group_concat` function  
    """
    function = 'group_concat'
    template = '%(function)s(%(field)s, "%(separator)s")'

现在我有这个查询:

Book.objects.values('date').annotate(total_sold=Sum('items_sold'), names=Concat('names', separator=',')

> [{'date': datetime.date(2016, 1, 5), 'total_sold': 5000, 'names': 'Book A, Book B'}, ...,]

现在的问题是书名被连接到字符串names。我可以定义分隔符,但我不知道如何将 names 转换为列表。 我可以稍后使用 split (names.split(separator)) 来完成此操作,但我认为这还不够保存,因为我的分隔符也可能是书名的一部分。 有什么建议吗?

最佳答案

没有提及您正在使用哪个数据库。但Django 1.9提供了某些postgres specific aggregate functions例如ArrayAgg 在这里非常有用:

from django.contrib.postgres.aggregates import ArrayAgg

Book.objects.values('date').annotate(total_sold=Sum('items_sold'), names=ArrayAgg('name'))

并且,这将聚合所有名称并将它们放入一个列表中。

关于python - 按日期对记录进行分组并添加字段列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36559088/

相关文章:

python - 设置 pymysql 以与 django、pytest 和 pytest-django 一起工作

python - 如何更改 Django 管理页面的名称?

python - 永久指定模型的使用

python - Django Slug 生成的 URL 返回 : 'No Fund matches the given query.'

python - 使用 subprocess.check_call() 运行 shell 命令时出错

python - 如何改变QTableView图像大小

python - SciPy:稀疏数据的 n 维插值

python - Pandas 直方图标签和标题

python - django loaddata 坚持将 xml 夹具读取为 ascii - 需要读取为 utf-8

python - 如何扩展 django oscar 客户模型字段?