Я использую аннотацию, которая подсчитывает положительные / отрицательные голоса при возврате списка статей:
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_count
и downvotes_count
сошли с ума и начали умножать (!) Результаты на количество категорий.
Таким образом, вопрос: «Есть ли способ использовать GROUP_CONCAT в Django, не разбивая аннотации SUM?»