#Modeling a polymorphic relationship for easy use

1 messages · Page 1 of 1 (latest)

prisma drum
#

What are some different ways to model a polymorphic relationship so it can easily be accessed in templates and keep things generally DRY?

I'll use a social platform as an example. A User can take a variety of different actions, make a post, update their status, etc. I'll call these Activities. I want to be able to access all of a user's activities from a user object. Many more activities exist, I'm looking for a DRY way to work with them using some sort of polymorphic strategy.

# ./models.py
class User(models.Model):
    ...

class Post(models.Model):
    User = models.ForeignKey(User)
    body = models.TextField()
    ...

class StatusUpdate(models.Model):
    User = models.ForeignKey(User)
    text = models.TextField()

Requirements

  1. Get a User's activities organized by activity type so I can neatly iterate over them from an HTML template.

I'm thinking something like this:

def user_activities(pk):
    User = User.objects.get(pk)
    activities = User.activities
    ...
    return activities
{
    'post': [{'body': 'My first post!'}, {'body': 'I love pineapple on pizza.'}],
    'status_update': [{'text': 'Hello!'}, {'text': 'Camping for the week'}],
}
  1. Serialize a User and it's activities. Deserialize a User and it's activities into the correct DB models.

A user should be able to export and import their profile along with all their content.

#

One approach I've tried is Multi-table inheritance, along with the InheritanceManager from Django model-utils.
https://django-model-utils.readthedocs.io/en/latest/managers.html#inheritancemanager

# ./models.py
class User(models.Model):
    ...

class Activity(models.Model)
    objects = InheritanceManager()
    
    User = models.ForeignKey(User, related_name="activities")
    ...

class Post(Activity):
    body = models.TextField()
    ...

class StatusUpdate(Activity):
    text = models.TextField()

With the help of StackOverflow I was able to figure out serialization with this approach, but not deserialization. https://stackoverflow.com/questions/24048595/django-rest-framework-multitable-model-inheritance-modelserializers-and-nested/42282447#42282447

#

One other approach I have to look into is a Generic relation.

snow walrus
#

I would probably reach for django-polymorphic 😅