Django使用相关查询器的第一个元素进行注释 [英] Django annotating with a first element of a related queryset
问题描述
我正在为一个简单的论坛创建一个数据库模型。用户应该能够创建线程,添加帖子并发布图像与他们的帖子。
I am creating a database model for a simple forum. Users should be able to create threads, add posts and post an image with their post.
在一个视图中,我想显示所有线程和:
In a view I would like to display all threads and:
- 获取线程中第一个帖子的字段,以显示帖子/创建日期的一部分等(包括可选图像)
- 获取线程中最后一篇文章的时间
- 在线程中计数帖子
- 计算线程中的图像
-
- get the fields of the first post in the thread to show a part of the post/creation date etc (including an optional image)
- get the time of the last post in the thread
- count posts in a thread
- count the images in a thread
我相信这不是真的没有执行 n
查询 n
线程,所以真正的问题是如何重新设计数据库,使之成为可能。
I believe this is not really possible without executing n
queries for n
threads, so the real question is how to redesign the database to make that possible.
class Thread(models.Model):
sticky = models.BooleanField()
...
class Post(models.Model):
thread = models.ForeignKey('Thread')
image = models.OneToOneField('Image', null=True, blank=True, default=None)
date = models.DateTimeField()
...
class Image(models.Model):
image = models.ImageField(...)
...
我的部分解决方案
在这一点上,我知道如何计数帖子和图像,但我不知道如何获取第一篇文章与此同时。我想到在 Thread
模型中添加额外的字段链接到第一个 Post
。
My partial solution
At this point I know how to count posts and images but I have no idea how to fetch the first post at the same time. I thought about adding additional field in the Thread
model linking to the first Post
.
我的查询强制我分别下载第一个帖子:
My query which forces me to download first posts separately:
Thread.objects.annotate(
replies=Count('post'),
images=Count('post__image'),
last_reply=Max('post_date')
)
推荐答案
您正在寻找的部分内容是 select_related 。您还需要像预期一样使用 annotate
。
Part of what you're looking for is select_related. You'll also need to use annotate
like you expected.
# I assume you have thread_id given to you.
last_reply = Post.objects.annotate(
thread_images=Count('thread__post_set__image__id', distinct=True),
replies=Count('thread__post_set__id', distinct=True),
).select_related('thread').filter(thread__id=thread_id).order_by('-post_date').first()
这篇关于Django使用相关查询器的第一个元素进行注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!