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
Django Custom Template Tags And Filters

Django Template Tags are simple Python functions that accept a value, an optional argument, and return a value to be displayed on the page.
First, ...

Continue Reading...
Best Practices of Using Django Celery in Django Social Auth

Best Practices of Using Django Celery in Django Social Auth.

Continue Reading...
How to use nested formsets in django

Django Formsets manage the complexity of multiple copies of a form in a view. By using formsets, you can know how many forms were their ...

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