Updated: Mar 25, 2020
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.
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.