Model Inheritance in Python Django

Amongst, other things, Django as a powerful framework allows you to directly map your object-oriented models to a database table structures and in doing so also builds relationships in the backend. A big part of object-oriented programming is Inheritance and the tutorial below demonstrates how to create 1:1 relationship between models.

Basic Background

Let’s assume that you are creating a site that has a base model called content that stores basic aspects of a content like title, description, created date, modified date and you have another model called video. Video inherits most of the content properties and in addition has its own unique qualifying properties like source, embed code, link etc. The code below solves for this scenario but can be extended to just about any concept.

Creating a base model

In your Django App create a model called Content.

from django.db import models
import uuid

# Create your models here.
class Content(models.Model):
    content_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    content_slug=models.CharField(max_length=100,unique=True)
    content_title=models.CharField(max_length=100)
    content_subtitle=models.CharField(max_length=255,null=True, blank=True)
    content_headline=models.CharField(max_length=100)
    content_modifieddate = models.DateField()
    content_createddate = models.DateField()


    def __str__(self):  # __unicode__ on Python 2
        return self.content_title


    class Meta:
        verbose_name = "Content"
        verbose_name_plural = "Content"

In the above code, we have created a model called Content and defined basic properties such as id, title, subtitle, headline, and such. Django maps this to a table called appname_content (where appname is your Django app name). Please note that this model inherits from model.Model.

Creating an inherited model

In your Django App create a model called Video. Instead of inheriting this model from model.Model, inherit it from the Content model you just created.

from django.db import models
from contentmanager.models import Content
import uuid

# Create your models here.
class Video(Content):
    video_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    video_link = models.URLField(null=True, blank=True)
    video_source_guid = models.CharField(max_length=255,null=True, blank=True)
    video_embed = models.TextField(null=True, blank=True)
    video_copyright = models.TextField(null=True, blank=True)

    def __str__(self):  # __unicode__ on Python 2
        return self.content_title

    class Meta:
        verbose_name = "Video"
        verbose_name_plural = "Videos"

In the above code, note that we are inheriting from Content and are able to access the Content properties by simply saying self.content_title. Also note that there is no explicitly foreign key relationship between Content and Video models. In the backend Django maps this to a table called appname_video (where appname is your Django app name). Please note that this model inherits from model.Model.

What happens in the database?

The cool part of this entire setup is Django manages the relationship for you in the backend. In this example, Django creates two tables appname_content and appname_video and establishes a 1:1 relationship between content and video. This field is called content_ptr_id in the database. You can access this using both the Django Framework preferred methods or the raw SQL methods.

Finally – one important tip…

In your admin module, if you do not want someone to have the ability to add a Content model object, then don’t register it. Enable the administrators to only add the Video object.  When you add the Video object, Django automatically prompts you to fill in the Content model properties before accepting the Video object properties. This approach provides one form for your administrators to complete as well as a normalized data store for your application.

We hope you enjoyed the tutorial. Let us know your thoughts via comments below.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: