Django:M2M 数据库注释查询



给定以下模型:

User
--------
Thread
--------
Post
--------
thread: ForeignKey(Thread)
read_by: ManyToManyField(User)

现在,我想检索当前登录用户阅读的特定线程的所有帖子。

因此,我从获取帖子开始:

Post.objects.filter(thread=self.thread)

现在,我不确定如何在将已读/未读标志设置为真/假的情况下进行注释。当前登录的用户可以使用变量self.request.user

我们可以在这里做一个EXISTS子查询,通过查询隐式构造的 Django 的 "through" 模型:

from django.db.models import Exists, OuterRef
post_read_query = Post.ready_by.through.objects.filter(
user_id=self.request.user.pk,
post_id=OuterRef('pk')
)

然后,我们在Exists子查询 [Django-doc] 中使用此post_read_query

Post.objects.filter(thread=self.thread).annotate(
is_read=Exists(post_read_query)
)

由此产生的Post对象将具有一个额外的属性.is_read,该属性True给定用户已读取Post(self.request.user)。

这将生成如下所示的查询:

SELECT post.*,
EXISTS(
SELECT U0.id, U0.user_id, U0.post_id
FROM post_read_by U0
WHERE U0.post_id = post.id AND U0.user_id =user_id
) AS is_read
FROM post
WHERE post.thread_id =thread_id

最新更新