我需要根据标签对每条消息进行注释。我必须使用 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))