如何在 Django 中使用 RawSQL 注释查询集

问题描述 投票:0回答:0

我需要根据标签对每条消息进行注释。我必须使用 RawSQL,因为真正的查询对 Django 不允许的聚合注释执行聚合。

精简款如下:

class Message(models.Model):
    text = models.CharField(max_length=250)

class Label(models.Model):
    message = models.ForeignKey(to=Message, on_delete=models.CASCADE)
    text = models.CharField(max_length=249, blank=False)

我可以通过删除

F('id')
并在有
%s
的地方硬编码一个 id 来获得用相同结果注释每条消息的查询。我怎样才能让这个查询对每条消息进行操作?请注意,这是我正在做的事情的简化查询。还要注意查询是messages = messages.annotate 因为这个注解前后都有ORM过滤器

raw_sql = """
    SELECT
        COUNT(DISTINCT labels_label.id) AS count
    FROM messages_message
    LEFT OUTER JOIN labels_label ON labels_label.message_id = messages_message.id
    WHERE messages_message.id = %s
    GROUP BY annotations_message.id
"""

messages = messages.annotate(count=RawSQL(raw_sql, F('id')))

编辑: 以下是我正在尝试的原始查询。 Django 给出了无法计算聚合的聚合的错误。

subq = Annotation.objects.filter(message_id=OuterRef('id'), reviewed=True).annotate(
            labels_combined=StringAgg(
                Concat(
                    F('labels__start'),
                    F('labels__end'),
                    F('labels__entity_id')
                ),
                output_field=CharField(),
                delimiter=';',
                order_by='labels__start',
                default=Value('')
            )
        ).values('labels_combined').distinct().annotate(count=Count('labels_combined')).values('count')
messages = messages.annotate(count=Subquery(subq))
django django-rest-framework django-queryset
© www.soinside.com 2019 - 2024. All rights reserved.