Django Polymorphic Model

In this blog, we will learn about the use of the Polymorphic model of Django.

Polymorphism: Polymorphism means the same function name (but different signatures) being uses for different types.

Example:
print(len("geeks")) output-:5
print(len([10, 20, 30])) output-:3

In the above example, len is a function that is used for different types. Polymorphic model is also based on polymorphism.

I did use the polymorphic model in many projects in excellence technologies.

So for using the Polymorphic model in Django, we will install dependencies first.

pip install django-polymorphic

After that, we will Update the settings file in the Django project:

INSTALLED_APPS += (
    'polymorphic',
    'django.contrib.contenttypes',
)

Now we will create a model in our Django app but we will use PolymorphicModel instead of Django, models.Model :

from polymorphic.models import PolymorphicModel

class Project(PolymorphicModel):
    topic = models.CharField(max_length=30)

class ArtProject(Project):
    artist = models.CharField(max_length=30)

class ResearchProject(Project):
    supervisor = models.CharField(max_length=30)

All models inheriting from your polymorphic models will be polymorphic as well. The relationship between parent and child Project is a parent class and an art project, whereas the research project is a child class.

Now we will create some objects using defined models.

Project.objects.create(topic="Department Party")
ArtProject.objects.create(topic="Painting with Tim", artist="T. Turner")
ResearchProject.objects.create(topic="SwallowAerodynamics",supervisor="Dr.Winter")

Now we will get polymorphic query results from project.

Project.objects.all()

Output:
[ <Project:         id 1, topic "Department Party">,
  <ArtProject:      id 2, topic "Painting with Tim", artist "T. Turner">,
  <ResearchProject: id 3, topic "Swallow Aerodynamics", supervisor "Dr. Winter"> ]

We got all the created objects from this query. Now we will see some queries for narrowing the result.

Use instance_of or not_instance_of for narrowing the result to specific subtypes:

Project.objects.instance_of(ArtProject)

Output:
 [ <ArtProject:id 2, topic "Painting with Tim", artist "T. Turner"> ] 
Project.objects.instance_of(ArtProject) | Project.objects.instance_of(ResearchProject)

Output:
 [ <ArtProject:id 2, topic "Painting with Tim", artist "T. Turner">,   <ResearchProject:id 3, topic "Swallow Aerodynamics",supervisor"Dr. Winter"> ] 

Polymorphic filtering: Get all projects where “Mr. Turner” is involved as an “artist” or “supervisor” (note the three underscores):

Project.objects.filter(Q(ArtProject___artist='T. Turner') | Q(ResearchProject___supervisor='T. Turner'))

Output:
[ <ArtProject: id 2, topic "Painting with Tim", artist "T. Turner">,
  <ResearchProject: id 4, topic "Color Use in Late Cubism", supervisor "T. Turner"> ]

This is basically all we need to know, as Django-polymorphic mostly works fully automatic and just delivers the expected results.

So what is the difference between simple models.Model and PolymorphicModels?

A simple model is easy to maintain, and it is sufficient for a single type of product. In simple models, we make the relation between tables using ForeignKey.

Pro

  • Easy to understand and maintain: It’s sufficient for a single type of product.

Con

  • Restricted to homogeneous products: It only supports products with the same set of attributes. Polymorphism is not captured or permitted at all. We can not inherit features from the base model.

The Polymorphic model provides lots of features as compared to a simple model.

Pro

  • Support for ForeignKey, ManyToManyField, OneToOneField descriptors.
  • Full admin integration.
  • Filtering/ordering of inherited models (___).
  • Filteringmodel types: instance_of(...) and not_instance_of(...)
  • Combining query sets of different models (qs3&nbsp;=&nbsp;qs1&nbsp;|&nbsp;qs2)
  • Support for custom user-defined managers.
  • Uses the minimum amount of queries needed to fetch the inherited models.
  • Disabling polymorphic behavior, when needed.

Con

  •  It’s complex to understand.
  • It’s hard to maintain in structure.
excellence-social-linkdin
excellence-social-facebook
excellence-social-instagram
excellence-social-skype