3

I'm specifically asking about Django here, but I'd appreciate any insight.

I'm currently writing up a basic social network. My plan is to allow users to make different kinds of posts (ie text posts, image posts, and video posts) and then allow them to access others' posts chronologically on their feed. The feed needs to contain all of these different kinds of posts.

I assumed that this would be trivial to do, by subclassing a general Post class into a TextPost class, an ImagePost class, and so on, then simply displaying each post on the feed.

#What I thought I would do
class Post(models.Model):
    user = models.ForeignKey(User, editable = False)
    time = models.TimeField(auto_now=True)

class TextPost(Post):
    content = models.TextField()

class ImagePost(Post):
    image = models.ImageField()

However, it doesn't look like Django is built to handle this; when I try to get a list of Posts, Django returns the posts without the subclass fields, ie without the "content" or "image" fields.

As I see it, I have two choices:

  1. Add more fields to the Post class, so it contains "content", "image", "post", etc. I know that this is bad, since it would mean that many Post rows would be empty, it wouldn't scale to allow many different post types, and it would require a lot more code to make sure that, ie, a single Post didn't have both an image and a video.
  2. Use a workaround such as this InheritanceManager class to do what I want, despite what Django allows. Though I'm currently going ahead with this option since it does what I want to do, I'm leery of it since it seems strange that Django doesn't handle what seems to me to be a common issue (treating slightly different sibling models the same way) very simply, and I feel as though I've gone wrong somewhere.

To put it shortly, I want to display all of these slightly different subclasses of the same model in a list, and I don't know how to do it properly. I know that this question seems a bit subjective, but, at least to me, this problem just feels like it should have an obvious solution.

1

Presumably you might have a post that has an image AND text?

I suspect a better way to structure things would be instead of subclassing, think of it as a post that HAS an image, or HAS text.

This sounds like a good application of the component pattern

https://en.wikipedia.org/wiki/Entity–component–system

1

You could store the post in some sort of serialized form, lets say json, that you can create by serializing your sub classes.

This can be a property or method of the base class implemented there or overridden in the subclasses so the list will work. I don't know Django to tell you more but you get the general idea.

Json will also be better to send to the client to do the rest.

Another way could be to store subclass information in there and cast each record to the appropriate type if that applies to Django.

1

You can use Casting to cast the generic Post object into a specific TextPost or ImagePost. I'm not familiar with Python, but it looks like this is how you do Casting

p = (TextPost)MyPostInstance

At this point the variable p is of type TextPost and will expose all the attribute of that type.

You first might need to ensure that myPostInstance is of the type that you want to Cast into. Something like this:

if type(myPostInstance) is TextPost:
    p = (TextPost)MyPostInstance

I hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.