Django Model Inheritance
Published: 2023-03-01 11:14:41

Django is a popular web framework that allows developers to build web applications quickly and easily. One of the powerful features of Django is its support for model inheritance. Model inheritance enables developers to create new models by inheriting fields from existing models. This feature can be used to build complex data models that are easy to maintain and extend. In this article, we will explore Django model inheritance and its various types.

# Types of Model Inheritance

1. Abstract Base Classes
2. Multi-table Inheritance
3. Proxy Models

## Abstract Base Classes

Abstract Base Classes (ABCs) are model classes that cannot be instantiated. They are used as base classes for other models and provide common fields and methods that can be reused by other models. ABCs can be created using the `abstract` attribute in the model's Meta class.

```python
from django.db import models

class AbstractPerson(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.EmailField()

    class Meta:
        abstract = True

class Employee(AbstractPerson):
    job_title = models.CharField(max_length=100)
    salary = models.IntegerField()

class Customer(AbstractPerson):
    address = models.CharField(max_length=200)
    phone_number = models.CharField(max_length=20)

```

In the above example, `AbstractPerson` is an ABC that defines the common fields for `Employee` and `Customer`. `Employee` and `Customer` inherit the fields from `AbstractPerson` and add their own fields.

## Multi-table Inheritance

Multi-table inheritance is a type of inheritance in which each model in the inheritance hierarchy is mapped to its own database table. This allows each model to have its own fields and methods, but also share the fields and methods of its parent model. Multi-table inheritance can be created by defining a model that inherits from another model.

```python
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.EmailField()

class Employee(Person):
    job_title = models.CharField(max_length=100)
    salary = models.IntegerField()

class Customer(Person):
    address = models.CharField(max_length=200)
    phone_number = models.CharField(max_length=20)
```

In the above example, `Employee` and `Customer` inherit from `Person`. Each model has its own table in the database, but they share the fields defined in `Person`.

```python
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.EmailField()

class Employee(Person):
    job_title = models.CharField(max_length=100)
    salary = models.IntegerField()

    class Meta:
        proxy = True

class Manager(Employee):
    class Meta:
        proxy = True

    def get_employees(self):
        return Employee.objects.filter(job_title='Manager', salary__gt=self.salary)

```

In the above example, `Employee` is a concrete model that inherits from `Person`. `Manager` is a proxy model that inherits from `Employee`. `Manager` does not add any new fields, but it does add a new method, `get_employees()`, that returns all the employees with the job title of "Manager" and a higher salary than the manager.