Problem
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
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(...)
...
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')
)