Конкатенация полей внешнего ключа с разделителем Django

Допустим, у меня есть 2 модели с отношением внешнего ключа, которые используются для связывания книг:

class Bundle(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    name = models.CharField(max_length=20)
    isbn = models.CharField(max_length=13)
    bundle = models.ForeignKey(Bundle)

мы будем идентифицировать пачки, объединяя номера ISBN с разделителем следующим образом:

123456788 & 123456789

Для дальнейшего экспорта списка доступных пакетов для дальнейшей обработки нам нужен этот номер.

Я знаю, что могу использовать:

for bundle in Bundle.objects.all():
    complex_isbn = ' & '.join(bundle.book_set.all().values_list('isbn', flat=True))

Но это было бы слишком медленно для реальных целей. Есть ли способ использовать annotate для достижения этой цели? Если да, то как? Я с трудом пытаюсь найти в документации, как выполнить конкатенацию нескольких записей внешнего ключа.

Вы можете воспользоваться агрегатной функцией StringAgg [Django-doc], которая доступна только для PostgreSQL. Таким образом, вы можете аннотировать Bundles сложным ISBN:

from django.contrib.postgres.aggregates import StringAgg

Bundle.objects.annotate(
    complex_isbn=StringAgg('isbn', delimiter=' & ')
)

У Bundle, возникающих из этого кверисета, будет дополнительный атрибут .complex_isbn.

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