Go deep into the inheritance relationship of Django ORM

Source: Internet
Author: User
Document directory
  • JOINED ing
  • TABLE_PER_CLASS ing
  • SINGLE_TABLE ing
  • Proxy Model
  • Multi-Inheritance
  • Summary

In ORM, object references are usually mapped to foreign keys. However, for inheritance, relational databases do not have natural and effective methods. From the perspective of data storage, there are several ways to map the inheritance relationship (refer to the InheritanceType. Definition in JPA ):

  1. Use a single table, called SINGLE_TABLE in JPA. The entire inheritance tree shares a table. Use a unique table that contains all fields of the base class and subclass.
  2. Each specific class is a table, which is called TABLE_PER_CLASS in JPA. In this way, each table contains a specific class and all the fields of the parent class on the inheritance tree. Because multiple tables have repeated fields, fields are redundant throughout the inheritance tree.
  3. Each class is a table, and the inheritance relationship is represented by the JOIN Operation of the table. JOINED is called in JPA. In this way, each table only contains fields defined in the class, and there is no redundant field. However, you must operate on the table corresponding to the subclass and all parent classes at the same time.

Django's ORM also supports the above three inheritance policies. It also supports ing of proxy models and multi-inheritance relationships thanks to the dynamic characteristics of python.

JOINED ing

If Model inheritance is implemented in Django, the following is true:

from django.db import models

class Person(models.Model):
name = models.CharField(maxlength=10)

class Man(Person):
job = models.CharField(maxlength=20)

class Woman(Person):
makeup = models.CharField(maxlength=20)

When you run the sqlall command using manage. py, the following result is displayed:

CREATE TABLE "uom_person" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(10) NOT NULL
)
;

CREATE TABLE "uom_man" (
"person_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "uom_person" ("id"),
"job" varchar(20) NOT NULL
)
;

CREATE TABLE "uom_woman" (
"person_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "uom_person" ("id"),
"makeup" varchar(20) NOT NULL
)
;

It can be seen that Django ORM uses the JOINED method by default to map the inheritance relationship.

TABLE_PER_CLASS ing

To implement a table for each specific class, you only need to specify the parent class as an abstract class, so that the table corresponding to the parent class will not be created, copy the fields of the parent class to the subclass to map the fields. As follows:

from django.db import models

class Person(models.Model):
name = models.CharField(max_length=10)

class Meta:
abstract = True

class Man(Person):
job = models.CharField(max_length=20)

class Woman(Person):
makeup = models.CharField(max_length=20)

Sqlall result:

CREATE TABLE "uom_man" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(10) NOT NULL,
"job" varchar(20) NOT NULL
)
;

CREATE TABLE "uom_woman" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(10) NOT NULL,
"makeup" varchar(20) NOT NULL
)
;

When the parent class is declared as abstract, the class will not have the objects attribute. That is to say, there is no Manager method, and all data operations cannot be performed, and only child classes can be performed.

SINGLE_TABLE ing

Based on TABLE_PER_CLASS, If you specify that the ing Table Name of the Child class is the same as that of the parent class, the Child class and the parent class will be mapped to the same table, and all child classes will be specified in this way, you can achieve SINGLE-_TABLE ing:

from django.db import models

class Person(models.Model):
name = models.CharField(max_length=10)
class Meta:
abstract = True

class Man(Person):
job = models.CharField(max_length=20)
class Meta:
db_table = 'oum_person'

class Woman(User):
makeup = models.CharField(max_length=20)

Sqlall result:

CREATE TABLE "oum_person" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(10) NOT NULL,
"job" varchar(20) NOT NULL
)
;

CREATE TABLE "uom_woman" (
"user_ptr_id" integer NOT NULL PRIMARY KEY,
"makeup" varchar(20) NOT NULL
)
;

In the above example, only one subclass is specified. It can be seen that because it is specified on the subclass, Django ORM is more flexible and can control the ing mode of a single subclass to implement any ing structure.

Proxy Model

There is a common scenario: to use classes in some libraries (lib), you just want to extend some methods without changing the data storage structure. In Python, you can add the constraint proxy = True to the Meta class. In this case, the "subclass" is called the "parent class" proxy class. The subclass can only add methods, but not attributes. For example, in the above example, if you want the Person to inherit the User class that comes with Django and do not want to damage the data storage of the User class, you can specify the proxy = True of the Person:

from django.db import models
from django.contrib.auth.models import User

class Person(User):
# name = models.CharField(max_length=10)
class Meta:
proxy = True

def do_something(self):
...

class Man(Person):
job = models.CharField(max_length=20)

class Woman(Person):
makeup = models.CharField(max_length=20)

The result of sqlall is:

CREATE TABLE "uom_man" (
"user_ptr_id" integer NOT NULL PRIMARY KEY,
"job" varchar(20) NOT NULL
)
;

CREATE TABLE "uom_woman" (
"user_ptr_id" integer NOT NULL PRIMARY KEY,
"makeup" varchar(20) NOT NULL
)
;
Multi-Inheritance

Python supports multi-inheritance. Although multi-inheritance is not recommended at the Model layer, Django's ORM supports the following methods:

class Mixin1(models.Model):
attr1 = models.CharField(max_length=10)
class Mixin2(models.Model):
attr1 = models.CharField(max_length=10)
class Multiple(Mixin1,Mixin2):
attr3 = models.CharField(max_length=10)

The result of sqlall is:

CREATE TABLE "uom_mixin1" (
"id" integer NOT NULL PRIMARY KEY,
"attr1" varchar(10) NOT NULL
)
;

CREATE TABLE "uom_mixin2" (
"id" integer NOT NULL PRIMARY KEY,
"attr1" varchar(10) NOT NULL
)
;

CREATE TABLE "uom_multiple" (
"mixin2_ptr_id" integer NOT NULL UNIQUE REFERENCES "uom_mixin2" ("id"),
"mixin1_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "uom_mixin1" ("id"),
"attr3" varchar(10) NOT NULL
)
;

During Multi-inheritance, the first parent class is selected as the primary key management for the orm ing of the subclass, and other parent classes are used as the general foreign key management.

Summary

Django ORM is flexible in ing inheritance relationships. It not only implements the SINGLE_TABLE, TABLE_PER_CLASS, and JOINED methods agreed by JPA, but also supports flexible customization. It even uses the Dynamic Language Features of python, supports proxy models and multi-inheritance features. However, because of its flexibility, you must pay attention to it when using manage. the sqllall function of py can observe the generated SQL statements and verify the inheritance implementation mechanism to avoid unexpected problems.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.