15. Advanced models concepts_Model_inheritance_Notes_v1
15. Advanced models concepts_Model_inheritance_Notes_v1
Without inheritance:
——————————
class Student(models.Model):
name = models.CharField(max_length=30)
email = models.EmailField()
address = models.CharField(max_length=30)
rollno = models.IntegerField()
marks = models.IntegerField()
class Teacher(models.Model):
name = models.CharField(max_length=30)
email = models.EmailField()
address = models.CharField(max_length=30)
subject = models.CharField(max_length=30)
salary = models.FloatField()
Project:miproject1
————————-
D:\Babu_AdvModel_Inheritence>django-admin startproject miproject1
D:\Babu_AdvModel_Inheritence>cd miproject1
D:\Babu_AdvModel_Inheritence\miproject1>py manage.py startapp testapp
models.py
————-
class ContactInfo(models.Model):
name = models.CharField(max_length=30)
email = models.EmailField()
address = models.CharField(max_length=30)
class Meta:
abstract = True
class Student(ContactInfo):
rollno = models.IntegerField()
marks = models.IntegerField()
class Teacher(ContactInfo):
subject = models.CharField(max_length=30)
salary = models.FloatField()
settings.py
————-
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'midb_715am',
'USER':'root',
'PASSWORD':'root',
} }
admin.py
————
from testapp.models import Student,Teacher
admin.site.register(Student)
admin.site.register(Teacher)
Note:
ConcatInfo class is abstract class and hence table wo't be created.
This type of inheritance is applicable only at code level but not at database
level.
models.py
————
class ContactInfo1(models.Model):
name = models.CharField(max_length=30)
email = models.EmailField()
address = models.CharField(max_length=30)
class Student1(ContactInfo):
rollno = models.IntegerField()
marks = models.IntegerField()
class Teacher1(ContactInfo):
subject = models.CharField(max_length=30)
salary = models.FloatField()
admin.py
————
admin.site.register(Student1)
admin.site.register(Teacher1)
admin.site.register(ContactInfo1)
-->In this case 3-tables will be craeted and child table will maintain pointer to parent
table to refer the common properties.
Ex:
class Person(models.Model):
name = models.CharField(max_length=30)
age = models.IntegerField()
class Employee(Person):
eno = models.IntegerField()
esal = models.FloatField()
class Manager(Employee):
exp = models.IntegerField()
team_size = models.IntegerField()
admin.py
--------------
admin.site.register(Person)
admin.site.register(Employee)
admin.site.register(Manager)
mysql>desc testapp_person
mysql>desc testapp_employee
mysql>desc testapp_manager
4).Multiple Inheritance:
———————————
-->If model class extends multiple parent classes simultaneously then such type of
inheritance is called as multiple inheritance.
Ex:
class Parent1(models.Model):
f1 = models.CharField(max_length=30)
f2 = models.CharField(max_length=30)
class Parent2(models.Model):
f3 = models.CharField(max_length=30,primary_key=True)
f4 = models.CharField(max_length=30)
class Child(Parent1,Parent2):
f5 = models.CharField(max_length=30)
f6 = models.CharField(max_length=30)
Note:
1).Parent classes should not contain common fields, otherwise will get an error.
2).Internally this inheritance also multi table inheritance.
manager = Employee.objects
emp_list = manager.all()
-->Go to shell
>>> from testapp.models import Person
>>> type(Person.objects)
<class 'django.db.models.manager.Manager'>
Based on our requirement, we can define and use our own custom model managers.
models.py
————
class Employee(models.Model):
eno = models.IntegerField()
ename = models.CharField(max_length=30)
esal = models.FloatField()
eaddr = models.CharField(max_length=64)
admin.py
————
from testapp.models import Employee
class EmployeeAdmin(admin.ModelAdmin):
list_display = ['eno','ename','esal','eaddr']
admin.site.register(Employee,EmployeeAdmin)
populate.py
—————
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','miproject2.settings')
import django
django.setup()
from testapp.models import Employee
from faker import Faker
from random import *
faker = Faker()
def populate(n):
for i in range(n):
feno = randint(1001,9999)
fename = faker.name()
fesal = randint(10000,20000)
feaddr = faker.city()
emp_record = Employee.objects.get_or_create(
eno=feno,
ename=fename,
esal=fesal,
eaddr=feaddr)
n = int(input('Enter Number Of Employees:'))
populate(n)
print(f'{n} Records inserted successfully.....')
views.py
———-
from testapp.models import Employee
def display_view(request):
emp_list = Employee.objects.all()
return render(request,'testapp/index.html',{'emp_list':emp_list})
index.html
————
<body>
<div class="container" align='center'>
<h1>Welcome To Employee List</h1>
<table border="3">
<thead>
<th>Employee Number</th>
<th>Employee Name</th>
<th>Employee Salary</th>
<th>Employee Address</th>
</thead>
{% for emp in emp_list %}
<tr>
<td>{{emp.eno}}</td>
<td>{{emp.ename}}</td>
<td>{{emp.esal}}</td>
<td>{{emp.eaddr}}</td>
</tr>
{% endfor %}
</table>
</div>
</body>
models.py
————
class CustomManager(models.Manager):
def get_queryset(self):
qs = super().get_queryset().order_by('eno')
return qs
class Employee(models.Model):
objects = CustomManager()
-->Based on our requiremeent, we can define our own methods also inside
CustomManager class
class CustomManager(models.Manager):
def get_emp_sal_eange(self,minsal,maxsal):
qs = super().get_queryset().filter(esal__range=(minsal,maxsal))
return qs
def get_emp_sorted_by(self,param):
qs = super().get_queryset().order_by(param)
return qs
views.py
————
emp_list = Employee.objects.get_emp_sal_eange(19000,20000)
emp_list = Employee.objects.get_emp_sorted_by('ename')
emp_list = Employee.objects.get_emp_sorted_by('-esal')
-->In this inheritance, a separate new table will not be created, and the new proxy
model will also point to the same old table.
class Employee:
fields
class ProxyEmployee(Employee):
class Meta:
proxy = True
-->Both Employee and ProxyEmployee are pointing to the same table only.
models.py
————-
class CustomManager1(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(esal__gte=18000)
class CustomManager2(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(esal__lte=12000)
class CustomManager3(models.Manager):
def get_queryset(self):
return super().get_queryset().order_by('eno')
class Employee(models.Model):
objects = CustomManager1()
class ProxyEmployee1(Employee):
objects = CustomManager2()
class Meta:
proxy = True
class ProxyEmployee2(Employee):
objects = CustomManager3()
class Meta:
proxy = True
admin.py
————
class ProxyEmployee1Admin(admin.ModelAdmin):
list_display = ['eno','ename','esal','eaddr']
admin.site.register(ProxyEmployee1,ProxyEmployee1Admin)
class ProxyEmployee2Admin(admin.ModelAdmin):
list_display = ['eno','ename','esal','eaddr']
admin.site.register(ProxyEmployee2,ProxyEmployee2Admin)
views.py
———-
emp_list = Employee.objects.all()
emp_list = ProxyEmployee1.objects.all()
emp_list = ProxyEmployee2.objects.all()