Django使用相关查询器的第一个元素进行注释 [英] Django annotating with a first element of a related queryset

查看:196
本文介绍了Django使用相关查询器的第一个元素进行注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为一个简单的论坛创建一个数据库模型。用户应该能够创建线程,添加帖子并发布图像与他们的帖子。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆