Поле аннотации набора запросов Django должно быть списком / набором запросов

Я пытаюсь использовать аннотацию django для создания поля набора запросов, которое представляет собой список значений некоторого связанного атрибута модели.

queryset = ...
qs = queryset.annotate(
    list_field=SomeAggregateFunction(
        Case(When(related_model__field="abc"), then="related_model__id")
    ),
    list_elements=Count(F('list_field'))
)

Я думал о соединении всех этих идентификаторов с каким-то разделителем, но я не знаю соответствующих функций. Другое решение состоит в том, чтобы сделать list_field queryset, Я знаю, что этот синтаксис неправильный. Спасибо за любую помощь.

2 ответа

Решение

Если вы используете postgresql а также django >= 1.9 Вы можете использовать специальные функции агрегирования postgres, например: ArrayAgg:

Возвращает список значений, включая нули, объединенные в массив.

В случае, если вам нужно объединить эти значения с помощью разделителя, вы также можете использовать StringAgg,

Я сделал что-то подобное:

qs = queryset \
    .annotate(
        field_a=ArrayAgg(Case(When(
            related_model__field="A",
            then="related_model__pk")
        )),
        field_b=ArrayAgg(Case(When(
            related_model__field="B",
            then="related_model__pk")
        )),
        field_c=ArrayAgg(Case(When(
            related_model__field="C",
            then="related_model__pk")
        ))
    )

Теперь есть списки None или же pk под каждым field_a, field_b а также field_c для каждого объекта в queryset. Вы также можете определить другое значение по умолчанию для Case вместо None,

Другие вопросы по тегам