在Django中使用GROUP_CONCAT和其他注释

时间:2018-04-26 10:40:35

标签: mysql django django-orm

我使用一个注释,在返回文章列表时计算upvotes / downvotes:

queryset = queryset.annotate(
        upvotes_count=models.Sum(
            models.Case(
                models.When(likes__like_state=1, then=1),
                default=0,
                output_field=models.IntegerField()
            )
        )
    ).annotate(
        downvotes_count=models.Sum(
            models.Case(
                models.When(likes__like_state=-1, then=1),
                default=0,
                output_field=models.IntegerField()
            ))
    )

但每篇文章也有一些类别作为ManyToMany相关领域,我需要以逗号分隔的方式返回这些类别,所以我写了这个函数:

class GroupConcat(models.Aggregate):

    function = 'GROUP_CONCAT'
    template = "%(function)s(%(distinct)s %(expressions)s %(separator)s)"

    def __init__(self, expression, distinct=False, separator=', ', **extra):
        super(GroupConcat, self).__init__(
            expression,
            distinct='DISTINCT' if distinct else '',
            separator="SEPARATOR '%s'" % separator,
            output_field=models.CharField(),
            **extra
        )

并将其添加到我的注释中:

queryset = queryset.annotate(category=GroupConcat('categories__name'))

它工作正常,但upvotes_countdownvotes_count发疯,并开始按类别数量乘以(!)结果。

所以问题是:“有没有办法在不破坏SUM注释的情况下在Django中使用GROUP_CONCAT?”

1 个答案:

答案 0 :(得分:0)

非常好的解决方案。 但是要对分组字段进行操作,您应该使用order_by语句。 例如:

Store.objects.all()。values('value')。order_by('value')。annotate(stores = GroupConcat('id'))

将生成sql语句

SELECT storevalue,GROUP_CONCAT(storeid分隔符“,”)AS storesstore的{​​{1}}位置。store> 0 GROUP BY valuestorevaluestore ASC

,结果将是 价值,商店 1“ 16,27”

没有order_by,它将是这样的:

SELECT valuestore,GROUP_CONCAT(valuestore分隔符“,”)AS idstores的{​​{1}}位置。store> 0 GROUP BY storevalue ORDER BY storeid ASC

,结果将是 价值,商店 1 16 2 27