I have a Django app with classes for different things such as Post, Quote, Image, Link, etc. Like items in Tumblr. Each of these objects has a datetime.
I want to display a combined list of the 20 most recent items of all types. And I want to be able to page back through older items. ie, just like Tumblr's pages.
But I can't think how to do queries like this across many different types of object... Would I have to create a separate class, something like:
class CombinedItem(models.Model):
date = models.DateTimeField()
item_type = models.CharField() # eg, 'post', 'quote', 'image', 'link'
item_id = models.IntegerField()
And add a new entry to that whenever I add a new Post, Quote, Image, etc. And then, for my list, query that CombinedItem class for the most recent items, and then fetch the main details for each item it returns? If so, what's the most efficient way of doing all that? Thanks.
Your best bet would be to actually work in reverse. Each of those is a type of user-generated content, so they should all inherit from a common base:
class ContentItem(models.model):
# common fields here
class Post(ContentItem):
# post specific fields
....
Then, you can simply query the base model ContentItem
and get a list of everything.
The only potential issue is that the results are ContentItem
s and not Post
s, Quote
s, etc. However, in Django's implementation of MTI (multi-table inheritance), the child class is an attribute on the parent class. So a "Post" ContentItem
will have a .post
attribute from which you can access the Post
. You can combine this with hasattr
to create utility methods that you can use in your view. For example:
class ContentItem(models.Model):
...
def is_post(self):
return hasattr(self, 'post')
Then, in your template:
{% if content_item.is_post %}
<!-- do some post-specific rendering here -->
{% endif %}