我有两个模型:
class User(Model):
...
class Message(Model):
sender = ForeignKey(User, CASCADE, 'sent_msgs')
receiver = ForeignKey(User, CASCADE, 'rcvd_msgs')
ignored = BooleanField()
我正在尝试用用户的相关消息的总和(即sent_msgs
和rcvd_msgs
的总和来注释用户的查询集。此外,任何带有ignored=True
的消息都应被忽略。
我可以使用子查询使用RawSQL
来简单地做到这一点:
SELECT COUNT("messages_message"."id")
FROM "messages_message"
WHERE "messages_message"."ignored" = FALSE
AND (
"messages_message"."sender_id" = "users_user"."id"
OR
"messages_message"."receiver_id" = "users_user"."id"
)
queryset = queryset.annotate(msgs_count=RawSQL(that_query_above))
是否有一种无需使用RawSQL
的方法?
答案 0 :(得分:2)
我们可以在此处使用Subquery
[Django-doc]:
from django.db.models import Count, OuterRef, Subquery, Q
User.objects.annotate(
msgs_count=Subquery(
Message.objects.filter(
Q(sender_id=OuterRef('pk')) | Q(receiver_id=OuterRef('pk')),
ignored=False
).order_by().values('ignored').annotate(cn=Count('*')).values('cn')
)
)
然后产生一个查询,如:
SELECT auth_user.*,
(
SELECT COUNT(*) AS cn
FROM message U0
WHERE (U0.sender_id = auth_user.id OR U0.receiver_id = auth_user.id)
AND U0.ignored = False)
GROUP BY U0.ignored
) AS msgs_count
FROM auth_user