For the sake of brevity, let's say we have the following two classes in models.py
:
class ImagePost(models.Model):
image = models.ImageField(...)
# other Image related fields
class VideoPost(models.Model):
video = models.FileField(...)
# other Video related fields
In the urls.py
, I have urls that can be used to query either video or image posts. So, I can query them separately. But that is not what I want.
What I want is the following functionality: When my application connects to the Django server, it should be able to query both post types such that the resulting queried data contains both types (e.g. sorted based on the timestamps). I want to display all types based on their creation time.
My first thought was to put everything from both into one class like the following:
class Post(models.Model):
image = ...
# all image related fields
video = ...
# all video related fields
But that class has so many entries and somehow I do not like that solution.
Does somebody have another solution that can be used in such a case ?
While it sometimes results in confusion, you might be looking for model inheritance.
from django.db import models
class Post(models.Model):
headline = models.TextField()
def __str__(self):
return self.headline
class VideoPost(Post):
video = models.BooleanField(default=True)
class ImagePost(Post):
image = models.BooleanField(default=True)
This enables querying all posts, though you'll get Post
objects back from queries against Post.objects
(note that I did not use an abstract base class here because that would not provide the Post.objects
manager, which I assume you'll want to use). Example:
>>> from mt.models import *
>>> ImagePost(headline="Tasty images.").save()
>>> VideoPost(headline="Hooray for video!").save()
>>> Post.objects.all()
<QuerySet [<Post: Tasty images.>, <Post: Hooray for video!>]>
>>> i = Post.objects.all()[0]
>>> i
<Post: Tasty images.>
>>> i.imagepost
<ImagePost: Tasty images.>
>>> i.imagepost.image
True
Be very careful when considering this. The linked documentation goes into detail on a lot of points that are worth thinking about when you're deciding whether this is a good approach for your use case.