Overriding Django Model behaviour with Proxy Model

The main Usage of a proxy model is to override the main functionality of existing Model. It is a type of model inheritance without creating a new table in Database. It always query on original model with overridden methods or managers.

You can query, delete, edit, create etc on Proxy model but the effects will be on the original model.

You can define models as a proxy just by adding proxy = True in Meta class of model.

 

# Original Model

class Employee(models.Model):

    EmployeeType = (

        ("D", "Developer"),

        ("M", "Manager"),

    )

    name = models.CharField(max_length=55)

    type = models.CharField(choices=EmployeeType, max_length=1, default='D')

    def __str__(self):

        return self.name

# Model manager to use in Proxy model

class ManagerEmpManager(models.Manager):

    def get_queryset(self):

        return super(ManagerEmpManager, self).get_queryset().filter(

            type='M')

    def create(self, **kwargs):

        kwargs.update({'type': 'M'})

        return super(ManagerEmpManager, self).create(**kwargs)

# Proxy Model

class ManagerEmployee(Employee):

    objects = ManagerEmpManager()

    class Meta:

        proxy = True

In ManagerEmployee I have overridden create method to set type as M(or Manager). whenever you create an object for ManagerEmployee model the type will be set to 'M' and a new object will be created for Employee table. Whenever you query on ManagerEmpManager you will get all employees who are Managers(or type field as 'M'). 

In [1]: from AppName.models import Employee, ManagerEmployee

In [2]: e1 = Employee.objects.create(name="Monkey")

In [3]: e1

Out[3]: <Employee: Monkey>   # Employee object created with type 'D'

In [4]: e1.type

Out[4]: u'D'

In [2]: e2 = ManagerEmployee.objects.create(name="Cow")

In [6]: e2

Out[6]: <ManagerEmployee: Cow>    # object created with type 'M' for model ManagerEmployee(original model Employee)

In [3]: e2.type

Out[3]: u'M'

In [4]: ManagerEmployee.objects.all()    # To get all ManagerEmployee objects(or type 'M') as we defined in ManagerEmpManager class.

Out[4]: <QuerySet [<ManagerEmployee: Cow>]>
In [5]: Employee.objects.all()

Out[5]: <QuerySet [<Employee: Monkey>, <Employee: Cow>]>

Register ManagerEmployee model in admin.py file to get a separate interface for ManagersEmployee model.

Posted On 05 October 2017 By MicroPyramid


Need any Help in your Project?Let's Talk

Latest Comments
Set Up Travis CI For Django project

Travis CI is a continuous integration service used to build and test applications hosted at GitHub. Here are simple steps to add CI to you ...

Continue Reading...
Sending emails using sendgrid on heroku for a Django App

Integrate Sendgrid API to your Heroku app to deliver simplified emails like any notification emails, user signups etc.

Continue Reading...
Understanding Django model formsets in detail and their advanced usage.

Silmilar to the regular formsets, django also provide model formset that make it easy to work with django models. Django model formsets provide a way ...

Continue Reading...

Subscribe To our news letter

Subscribe and Stay Updated about our Webinars, news and articles on Django, Python, Machine Learning, Amazon Web Services, DevOps, Salesforce, ReactJS, AngularJS, React Native.
* We don't provide your email contact details to any third parties