Django中Model继承的三种方式

Django中Model的继承有三种:
1、抽象继承
2、多表继承
3、proxy model(代理model)

1、抽象继承

第一种抽象继承,创建一个通用父类,为了使父类不会被创建,在抽象父类的Meta中设置abstract=True就可以。子类会继承父类相同的字段.

子类模型Student就会有s_name, s_age, s_sex三个字段


class CommonInfo(models.Model):s_name = models.CharField(max_length=32)s_age = models.PositiveIntegerField(default=22)class Meta:abstract = Trueclass Student(CommonInfo):home_group = models.CharField(max_length=32)

对于内联的Meta类的继承,一般的,父类的Meta类的属性会继承给子类,子类也可以在自己的Meta中重写或者拓展父类的Meta,拓展的话主要是继承父类的Meta:


class CommonInfo(models.Model):...class Meta:abstract = Trueordering = ['name']class Student(CommonInfo):...class Meta(CommonInfo.Meta):db_table = 'student_info'

继承时,Django 会对基类的 Meta 内嵌类做一个调整:在安装 Meta 属性之前,Django 会设置 abstract=False。 这意味着抽象基类的子类不会自动变成抽象类。当然,你可以让一个抽象类继承另一个抽象基类,不过每次都要显式地设置 abstract=True 。

对于抽象基类而言,有些属性放在 Meta 内嵌类里面是没有意义的。例如,包含 db_table 将意味着所有的子类(是指那些没有指定自己的 Meta 内嵌类的子类)都使用同一张数据库表,一般来说,这并不是我们想要的。

2,多表继承

第二种多表继承,其中父类也是一个Django模型,并且会创建一个数据表,多表继承是Django中隐式的一对一关系:


class Place(models.Model):name = models.CharField(max_length=50)address = models.CharField(max_length=80)class Restaurant(Place):serves_hot_dogs = models.BooleanField()serves_pizza = models.BooleanField()

这里,MyPerson没有多创建数据表,MyPerson也是对Person的数据表进行操作,一般的,我们可以把MyPerson当做Person来使用,只是在do_something这个方法略有不同,比如


>>> p = Person.objects.create(first_name="foobar")
>>> MyPerson.objects.get(first_name="foobar")
<MyPerson: foobar>

代理模型和原模型的区别如下面:


class OrderedPerson(Person):class Meta:ordering = ["last_name"]proxy = True

这里,OrderedPerson并不是创建了一个表,而是代理排序方法。也就是说,使用Person的检索方法并不会按last_name排序,而使用OrderedPerson检索出来的结果是按last_name排序的。OrderedPerson使用与Person类一样的检索方法。

OrderPerson返回的queryset自然是Person的,这是当然的。我们不能要求django返回OrderedPerson类的queryset,因为OrderedPerson只是代理而已,又不是真实的数据库表类。

注意的是,proxy model不能继承于抽象类,这是因为代理model是操作连接数据库的,也不能多重继承~因为你多重继承了,代理model就不知道去哪个父类找属性了

如果不指定代理model的manage,则代理model会自动继承父类的manage。我们也可以手动设置代理model的manage,这样,代理模型和父类模型的manage就分开了

3、proxy model(代理model)

为代理模型添加manage有两种方法:

一是直接在代理模型中直接指定manage


class NewManager(models.Manager):...class MyPerson(Person):objects = NewManager()class Meta:proxy = True

另外一种是当你不想覆盖父类模型中的manage但又想添加额外的manage,我们可以新建一个抽象模型,然后定义其manage,之后继承该抽象模型,如:

# Create an abstract class for the new manager.
class ExtraManagers(models.Model):secondary = NewManager()class Meta:abstract = Trueclass MyPerson(Person, ExtraManagers):class Meta:proxy = True

Django中Model继承的三种方式相关推荐

  1. django文件上传到服务器,django上传文件的三种方式

    Django文件上传需要考虑的重要事项 文件或图片一般通过表单进行.用户在前端点击文件上传,然后以POST方式将数据和文件提交到服务器.服务器在接收到POST请求后需要将其存储在服务器上的某个地方.D ...

  2. Java中实现接口的三种方式您造吗?

    本文介绍了Java中实现接口的三种方式:常规实现方式.匿名内部类和 Lambda表达式实现方式.希望已经了解的同学可以重新温习一下,不了解的同学则从中受益! Java中接口最常规的实现方式 同学们都会 ...

  3. java中实现多线程的三种方式

    java中实现多线程的三种方式 1.实现多线程的方法: 在java中实现多线程的两途径:继承Thread类,实现Runable接口(Callable) 2.继承Thread类实现多线程: ​ 继承类T ...

  4. android获取自定义属性,android 自定义控件中获取属性的三种方式(转)

    第一种方法,直接设置属性值,通过attrs.getAttributeResourceValue拿到这个属性值. (1)在xml文件中设置属性值 android:layout_width="f ...

  5. UE4学习-在虚幻编辑器中打开VS的三种方式

    文章目录 方式一 方式二 方式三 在虚幻编辑器中打开VS的三种方式 方式一 在文件浏览器这里,选择C++类,然后在文件夹内,找到一个和截图中类似的图标,双击,即打开vs,并在vs中打开这个类的代码. ...

  6. java类初始数组_java中数组初始化的三种方式是什么

    java中数组初始化的三种方式是:1.静态初始化,如[int a[] = {2, 0, 1, 9, 2020}]:2.动态初始化,如[int[] c = new int[4]]:3.默认初始化,如[i ...

  7. 【查看linux中所有用户的三种方式】

    查看linux中所有用户的三种方式学习目标: 提示:通过使用 /etc/passwd 文件,getent 命令,compgen 命令这三种方法查看系统中用户的信息 用户信息存放位置: 提示:Linux ...

  8. java中Map遍历的三种方式

    Java中Map遍历的三种方式 前言 一:在for循环中使用entries实现Map的遍历: 二:在for循环中遍历key或者values,一般适用于只需要map中的key或者value时使用,在性能 ...

  9. Java中创建线程的三种方式

    Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)继承Thread类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行体. ...

最新文章

  1. ThinkPHP5.1接收post、get参数
  2. SharePoint KB
  3. 【NLP】到目前为止,机器学习与自然语言处理相遇的那些事
  4. CF525D-Arthur and Walls【贪心】
  5. C++学习之路 | PTA乙级—— 1083 是否存在相等的差 (20 分)(精简)
  6. java计算一个多边形的重心_2D凸多边形碰撞检测算法(二) - GJK(上)
  7. oracle先的lvm分配,LVM实战案例之LVM空间缩减(本次对PV,VG,LV等进行空间缩减)
  8. PP-OCR论文笔记
  9. linux安装 soapui_SoapUI命令行方式运行
  10. 幼儿园故事导入语案例_幼儿园故事教案导入语
  11. 快解析外网如何访问内网共享服务器
  12. java求素数的方式
  13. 2022-2028年中国知识产权行业竞争策略研究及未来前景展望报告
  14. 2020-11-22 Vue-10组件化开发(1)
  15. m277dw恢复出厂设置_惠普M277dw打印机使用说明书(惠普M277dw打印机用户手册PDF资料)V1.0 官方版...
  16. 阿里云iot mqtt
  17. 深度学习论文阅读图像分类篇(五):ResNet《Deep Residual Learning for Image Recognition》
  18. 【大数据AI人工智能】常见的归一化函数有哪些?分别用数学公式详细介绍
  19. aida64使用方法_最基础!AIDA64怎么用?AIDA64使用教程
  20. AZ-104认证考试攻略

热门文章

  1. 腾讯云上午突发故障 称运营商光缆中断所致
  2. 成功解决AttributeError: module 'numpy' has no attribute 'integer'
  3. DayDayUp:《复仇者联盟4:终局之战》娱乐闲谈——当灭霸碰上一个处女座的程序猿
  4. EL之Boosting之GB(DTR):利用梯度提升法解决回归(对多变量的数据集+实数值评分预测)问题
  5. TF之DD:利用Inception模型+GD算法生成更大尺寸的Deep Dream精美图片
  6. Paper:《Hidden Technical Debt in Machine Learning Systems—机器学习系统中隐藏的技术债》翻译与解读
  7. Hyperopt 入门指南
  8. Hibernate 之单向多对一映射及其衍生问题
  9. C#+uploadify3.1上传示例,可使用中文按钮
  10. 递归遍历文件夹,并添加到TreeView控件中