Конкатенация полей внешнего ключа с разделителем 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. Таким образом, вы можете аннотировать Bundle
s сложным ISBN:
from django.contrib.postgres.aggregates import StringAgg
Bundle.objects.annotate(
complex_isbn=StringAgg('isbn', delimiter=' & ')
)
У Bundle
, возникающих из этого кверисета, будет дополнительный атрибут .complex_isbn
.