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
Related Articles
Custom Password Less Authentication in Django

Authentication backends allow the ability to change what method checks your users credentials.

For web services, ie Facebook authentication, you don't have access to user ...

Continue Reading...
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...
Integration of 2checkout with django

Payment Gateways which facilitate communication within banks and Security is an integral component of all payment gateways, as sensitive data such as Credit Card Numbers ...

Continue Reading...
open source packages

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