相关行的Django ORM concat(通过ORM进行字符串连接吗?)

时间:2019-06-26 17:46:16

标签: django django-orm

两个简单的模型:

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

似乎Django的Concat无法做到这一点,现在我不确定是否可以实现所需的行为。

注意:PostgreSQL 9.5和Django 1.11。

2 个答案:

答案 0 :(得分:1)

由于您使用的是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'

答案 1 :(得分:0)

解决此问题的实际方法是使用aggregate类旁边的 StringAgg 方法:

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