django支持三种风格的模型继承:
1. 抽象类继承: 父类继承自models.Model, 但不会在数据库中生成相应的数据表。父类的属性列存储在其子类的数据表中
2. 多表继承: 多表继承的每个类都在数据库中生成相应的数据表管理数据
3. 代理模型继承: 父类用于在数据库中管理数据表, 子类不定义数据列,只定义查询的数据集的排序方式等元数据
抽象类继承
抽象类继承的作用是在多个表中有若干相同字段时,可以将这些字段统一定义在抽象基类中,免于重复定义这些字段
from django.db import models class MessageBase(models.Model): id = models.AutoField() content = models.CharField(max_length=100) user_name = models.CharField(max_length=80) pub_date = models.DateField() class Meta: abstract = True #定义本类为抽象类 class Moment(MessageBase): headline = models.CharField(max_length=50) LEVELS = ( ('1', 'Very Good'), ('2', 'Good'), ('3', 'Normal'), ('4', 'Bad'), ) class Comment(MessageBase): level = models.CharField(max_length=1, choices=LEVELS)
映射到数据库后,会建立两个数据表
moment: 字段有 id, content, user_name, pub_date, headline
comment: 字段有id, content, user_name, pub_date, level
多表继承
在多表继承中,无论是父表还是子表都会用数据库中对应的数据表维护模型数据;父类的字段不会重复地在多个子类的数据表中定义
from django.db import models class MessageBase(models.Model): id = models.AutoField() content = models.CharField(max_length=100) user_name = models.CharField(max_length=80) pub_date = models.DateField() class Moment(MessageBase): headline = models.CharField(max_length=50) class Comment(MessageBase): level = models.CharField(max_lenght=1, choices=LEVELS)
数据库中实际会生成3个数据表:
MessageBase: 字段有 id, content, user_name, pub_date
Moment: 字段有 id, headline
Comment: 字段有 id, level
而在实际应用 中,子类仍然可以直接引用父类定义的字段, 同时子类可以通过父类对象引用访问父类实例
m1 = Moment(user_name='Terry', headline='Hello World') m1.content = "reference parent field in subclass" m1.save() print m1.messagebase.content #通过小写的父类名可以引用父类的实例
代理模型继承
代理模型中的子类只用于管理父类的数据,而不实际存储数据;代理模型继承通过在子类的Meta中定义proxy=True实现
from django.db import models class Moment(models.Model): id = models.AutoField() headline = models.CharField(max_lenght=50) content = models.CharField(max_lenght=100) user_name = models.CharField(max_lenght=80) pub_date = models.DateField() class OrderedMoment(Moment): class Meta: proxy = True ordering = ["-pub_date"]