Reputation: 2309
I have two models called Thread
and Post
. A Thread has 0..*
posts.
Now, I need a query that gets all threads sorted by the datetime of the latest post in the thread. In case there is no post yet in the thread, the datetime of the thread creation is important.
Honestly, I am a bit overwhelmed with the database query.
Thread:
created_at = DateTimeField()
Post
thread = ForeignKey(Thread)
My current approach does not work:
newest = Post.objects.filter(thread=OuterRef('pk')).order_by('-created_at')
threads = Thread.objects.annotate(
latest_post=Case(
When(Exists(Subquery(newest.values_list('created_at')[:1])),
then=Value(Subquery(
newest.values_list('created_at')[:1]),
),
default=Value(Thread.created_at)))).order_by('-latest_post')
Can someone help me?
Upvotes: 3
Views: 283
Reputation: 476557
You can annotate these with the Max
aggregate [Django-doc], and use the Coalesce
function [Django-doc] as a fallback mechanism, like:
from django.db.models import Max
from django.db.models.functions import Coalesce
Thread.objects.annotate(
latest_post=Coalesce(Max('post__created_at'), 'created_at')
).order_by('-latest_post')
The latest_post
is thus the timestamp of the maximum created_at
of the related Post
objects. In case there are no related Post
objects, we fallback on the created_at
field of the Thread
.
Upvotes: 5