学者网学科建设网站,找个网站2021能看到,wordpress文章外链调用,如何生成自己的小程序Django中三种继承风格
抽象基类#xff1a;仅将父类用于子类公共信息的载体#xff0c;这样的父类永远都不会单独使用。多表继承#xff1a;继承了一个模型#xff08;可能来源其它应用#xff09;#xff0c;且想要每个模型都有对应的数据表。代理模型#xff1a;只想…Django中三种继承风格
抽象基类仅将父类用于子类公共信息的载体这样的父类永远都不会单独使用。多表继承继承了一个模型可能来源其它应用且想要每个模型都有对应的数据表。代理模型只想修改模型的 Python 级行为而不是以任何形式修改模型字段。
抽象基类
有很多模型需要公共信息的时候抽象基类就会有用比如一个后台管理系统都需要一些用于审计的字段。 例子
from django.db import modelsclass CommonInfo(models.Model):name models.CharField(max_length100)age models.PositiveIntegerField()class Meta:abstract Trueclass Student(CommonInfo):home_group models.CharField(max_length5)关于Meta继承 当一个抽象基类被建立Django 将所有你在基类中申明的 Meta 内部类以属性的形式提供。若子类未定义自己的 Meta 类它会继承父类的 Meta。Django 在安装 Meta 属性前对抽象基类的 Meta 做了一个调整——设置 abstractFalse。这意味着抽象基类的子类不会自动地变成抽象类。为了继承一个抽象基类创建另一个抽象基类你需要在子类上显式地设置 abstractTrue。 由于Python继承的工作方式如果子类从多个抽象基类继承则默认情况下仅继承第一个列出的类的 Meta 选项。为了从多个抽象类中继承 Meta 选项必须显式地声明 Meta 继承。 关于对 related_name 和 related_query_name 的使用 若你在 外键 或 多对多字段 使用了 related_name 或 related_query_name你必须为该字段提供一个 独一无二 的反向名字和查询名字。这在抽象基类中一般会引发问题因为基类中的字段都被子类继承且保持了同样的值包括 related_name 和 related_query_name。 为了解决此问题当你在抽象基类中也只能是在抽象基类中使用 related_name 和 related_query_name部分值需要包含 ‘%(app_label)s’ 和 ‘%(class)s’。 多表继承 Django 支持的第二种模型继承方式是层次结构中的每个模型都是一个单独的模型。每个模型都指向分离的数据表且可被独立查询和创建即多表继承它是使用隐式的 OneToOneField 连接子类和父类。 例子
from django.db import modelsclass Place(models.Model):name models.CharField(max_length50)address models.CharField(max_length80)class Restaurant(Place):serves_hot_dogs models.BooleanField(defaultFalse)serves_pizza models.BooleanField(defaultFalse)关于Meta的多表继承 多表继承情况下子类不会继承父类的 Meta。所有 Meta 类选项已被应用至父类在子类中再次应用会导致行为冲突与抽象基类中应用场景对比这种情况下基类并不存在。 故子类模型无法访问父类的 Meta 类。不过有限的几种情况下若子类未指定 ordering 属性或 get_latest_by 属性子类会从父类继承这些。 如果父类有排序而你并不期望子类有排序你可以显式的禁止它: class ChildModel(ParentModel):# ...class Meta:# Remove parents ordering effectordering []代理模型 代理模型继承的目的为原模型创建一个代理。你可以创建删除和更新代理模型的实例所以的数据都会存储的像你使用原模型未代理的一样。不同点是你可以修改代理默认的模型排序和默认管理器而不需要修改原模型。 代理模型就像普通模型一样申明。你需要告诉 Django 这是一个代理模型通过将 Meta 类的 proxy 属性设置为 True。 例子
from django.db import modelsclass Person(models.Model):first_name models.CharField(max_length30)last_name models.CharField(max_length30)class MyPerson(Person):class Meta:proxy Truedef do_something(self):# ...pass