I have a model Page, which can have Posts on it. What I want to do is get every Page, plus the most recent Post on that page. If the Page has no Posts, I still want the page. (Sound familiar? This is a LEFT JOIN in SQL).
Here is what I currently have:
Page.objects.annotate(most_recent_post=Max('post__post_time'))
This only gets Pages, but it doesn’t get Posts. How can I get the Posts as well?
Models:
class Page(models.Model):
name = models.CharField(max_length=50)
created = models.DateTimeField(auto_now_add = True)
enabled = models.BooleanField(default = True)
class Post(models.Model):
user = models.ForeignKey(User)
page = models.ForeignKey(Page)
post_time = models.DateTimeField(auto_now_add = True)
Depending on the relationship between the two, you should be able to follow the relationships quite easily, and increase performance by using
select_relatedTaking this:
You can follow the forward relationship (i.e. get all the
postsand their associated pages) efficiently usingselect_related:This will result in only one (larger) query where all the page objects are prefetched.
In the reverse situation (like you have) where you want to get all
pagesand their associatedposts,select_relatedwon’t work. See this,this and this question for more information about what you can do.