Django ORM concat для связанных строк (объединение строк через ORM?) - PullRequest
0 голосов
/ 26 июня 2019

Две простые модели:

class Thread(models.Model):
    pass

class Message(models.Model):
    thread = models.ForeignKey(Thread, related_name='messages')

Возможно ли сделать что-то подобное?

>>> thread = Thread.objects.create()

>>> Message.objects.create(thread=thread, content='One')
>>> Message.objects.create(thread=thread, content='Two')
>>> Message.objects.create(thread=thread, content='Three')

>>> t = Thread.objects.annotate(
        message_content=MySuperConcat('messages__content')).first()
>>> t.messages_content

OneTwoThree

Похоже, что Concat Джанго не может этого сделать, и теперь я не уверен, возможно ли вообще желаемое поведение.

Примечание: PostgreSQL 9.5 и Django 1.11.

1 Ответ

1 голос
/ 26 июня 2019

Поскольку вы используете Postgres, вы можете использовать StringAgg [docs] , хотя в версии 1.11 вы не сможете его заказать.

from django.contrib.postgres.aggregates import StringAgg
Thread.objects.annotate(arr=StringAgg('messages__content', delimiter='')).values()
>>> 'ThreeTwoOne'

ОБНОВЛЕНИЕ:

Если вы не на 100% настроены на то, что код полностью выполняется через ORM, довольно просто сделать что-то вроде

vals = Thread.objects.filter(id=1).annotate(m=F('messages__content')).order_by('messages__id').values('m')
''.join([x['m'] for x in vals])
>>> 'OneTwoThree'
...