The model snapshot used in a recently developed project is just ready to be used Django The model makes , So I looked at it Django Several ways of model inheritance , Because the project only uses Django As a background management, the migration file definition database is not directly generated . In the end, these model inheritance schemes have not been adopted, but it is still necessary to summarize the records here .
Abstract inheritance : Create a generic parent class , But we don't want the parent class to be created , But all subclasses that inherit from this parent class have fields of this abstract parent class . On the Meta Set in abstract=true That is to say .
Examples of application scenarios :
We have two models Book 、Author We need both of these models createdAt as well as updatedAt as well as enable Field , If we define each model once, it will be a little redundant , Here, you can use abstract model inheritance , We define a parent class that contains createdAt as well as updatedAt as well as enable Field Book、Author These two classes can inherit the parent class
from django.db import models
# Define the parent abstract class
class Base(models.Molde):
createdAt = models.BigIntegerField(verbose_name=' Creation time ')
updatedAt = models.BigIntegerField(verbose_name=' Update time ')
enable = models.BooleanField(verbose_name=' Is it available ')
class Meta:
# Indicates that the model is an abstract class and will not be created
abstract = True
# Defining subclasses , The subclass contains all the attributes in the parent class and the attributes defined by itself
class Book(Base):
name = models.CharField(max_length=32)
class Author(Base):
name = models.CharField(max_length=32)
For multi table inheritance, its parent class is also a Django Model , And the parent class will create a data table , Multi table inheritance yes Djnago An implicit one-to-one relationship in :
# Parent class
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
# Subclass
class Restaurant(Place):
serves_hot_dogs = models.BooleanField()
serves_pizza = models.BooleanField()
here Restaurant and Place It's a one-to-one relationship , When we are executing django The relationship between them can be seen when the migration file command is generated .
Be careful ️: When using multi table inheritance, the parent and child classes must use django Migration generated tables , Otherwise, the table model cannot be used normally
Model tables using proxy mode will not be created , In fact, they all point to the same model .
from django.db import models
class Person(models.Model):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=32)
class OrderPerson(Person):
class Meta:
ordering = ['id']
proxy = True
there OrderPerson Will not be created , When we are modifying OrderPerson The data in the Person The data in will also be modified .
Be careful ️:proxy model Cannot inherit abstract classes , This is because the agent model It is used to operate linked databases, and multiple inheritance is not allowed , If you use multiple inheritance proxy model I don't know how to find that father .
Suppose we have the following two models Book、Author
class Author(models.Model):
id = models.BigAutiField(primary_key=True)
name = models.CharField(max_length=32)
class Book(models.Models):
name = models.CharField(max_lenght=32)
first_author = models.ForeignKey(Author, no_delete=models.CASCADE)
secend_author = models.ForeignKey(Author, no_delete=models.CASCADE)
The above model defines that our book may have multiple authors ,first_author secend_author All related Author This table , If we run this code, we will get an error .
reason : Two foreign key reverse association names pointing to a model conflict ,django By default, each main table object has a foreign key attribute , It can be used to query all the information about the sub table , By default, the name of this attribute is the name of the child table in lowercase plus _set, and first_author and secend_author This attribute defaults to book_set, Lead to conflict , terms of settlement : We can define related_name To manually define the attribute , The correct code is as follows :
class Author(models.Model):
id = models.BigAutiField(primary_key=True)
name = models.CharField(max_length=32)
class Book(models.Models):
name = models.CharField(max_lenght=32)
first_author = models.ForeignKey(Author, no_delete=models.CASCADE, related_name='first_author')
secend_author = models.ForeignKey(Author, no_delete=models.CASCADE, related_name='secend_author')