Django ORM: Агрегатор текста на подзапросе

Я бился головой над этим:

У меня есть 2 модели, и я пытаюсь разработать пользовательский менеджер/кейрисет, который позволит мне аннотировать к каждой Series id из связанных пазлов, удовлетворяющих определенным условиям в формате '2,13,26'.

Упрощенные модели:

class Series(models.Model):
    puzzles = models.ManyToManyField(
        Puzzle, through='SeriesElement', related_name='series')
    is_public = models.BooleanField(null=False, blank=False, default=False)

class Puzzle(models.Model):
    pass

мой пользовательский агрегатор:

from django.db.models.aggregates import Aggregate
from django.db.models.functions import Coalesce
from django.db.models.fields import CharField
from django.db.models.expressions import Value

class GroupConcat(Aggregate):
    """
    according to https://stackoverflow.com/questions/10340684/group-concat-equivalent-in-django
    according to https://stackoverflow.com/a/55216659
    would be compatible with MySQL and SQLite
    """
    function = 'GROUP_CONCAT'

    def __init__(self, expression, distinct=False, ordering=None, **extra):
        super(GroupConcat, self).__init__(expression,
                                          distinct='DISTINCT ' if distinct else '',
                                          ordering=' ORDER BY %s' % ordering if ordering is not None else '',
                                          output_field=CharField(),
                                          **extra)


    def as_sqlite(self, compiler, connection, **extra):
        return super().as_sql(compiler,
                              connection, 
                              template='%(function)s(%(distinct)s%(expressions)s%(ordering)s)',
                              **extra)

один ориентир для достижения моей цели:

pzl_sub = apps.get_model('puzzles', 'Puzzle').objects.filter(series__id= OuterRef('id'))
pzl_sub = pzl_sub.filter(series_elements__isnull=False).add_nb_public_series().filter(nb_public_series=5)
pzl_ids= pzl_sub.order_by().values('id')
qs = Series.objects.annotate(id_str_pzl = GroupConcat(pzl_ids))

Я получаю только один puzzle.id, который соответствует заданным условиям, вместо конкатената всех puzzle.id, которые соответствуют условиям

Есть подсказка, что я делаю неправильно?

После нескольких дней борьбы и тестирования всего и вся, я наконец-то разобрался:

pzl_sub = apps.get_model('puzzles', 'Puzzle').objects.filter(series__id= OuterRef('id'))
pzl_sub = pzl_sub.filter(series_elements__isnull=False).add_nb_public_series().filter(nb_public_series=5)
pzl_ids= pzl_sub.order_by().values('series__id')
qs = Series.objects.annotate(id_str_pzl = Subquery(pzl_ids.annotate(result=GroupConcat('id')).order_by().values('result')))

в pzl_ids, нужно выделить values('series__id')

и только на втором шаге, нам нужно аннотировать агрегатором, и снова выделить полученное значение ...

Вернуться на верх