I am trying to get the maximum value from merging the results from two separate tables. I am trying to get the most updated comment for a Post. I have a model Comment
that can be accessed by Post.comments
. I also have a body that is separate of the Post
that can be accessed by Post.body
. Both comments and body have a field when
that is a DateTimeField
. I would like to return a sorted queryset by most recent activity such that the a Post with the most recent comment or body is shown first.
Assume the models look like this:
class Body(models.Model):
when = models.DateTimeField(default=datetime.datetime.now)
class Post(models.Model):
body = models.ForeignKey(Body)
class Comment(models.Model):
post = models.ForeignKey(Post, related_name='comments')
when = models.DateTimeField(default=datetime.datetime.now)
I would like the result to remain a queryset if possible since I continue to process it and further pass it into a paginator to limit results.
Basically, I would like to be able to call:
q = Post.annotate(
activity=Max(
Union('comments__when', 'body__when')
)
)
q = q.order_by('-activity')
But I don't know how to accomplish that Union.
I believe the SQL that accomplishes what I'm looking for is comparable to:
SELECT
...
IF(MAX(c.`when`), MAX(c.`when`), b.`when`) AS `activity`
...
FROM `post` p
...
LEFT OUTER JOIN `comment` AS c
ON c.`post_id`=p.`id`
LEFT OUTER JOIN `body` AS b
ON p.`body_id`=b.`id`
...
Can such a customized annotation and Join be accomplished?