• Django模型继承之Meta继承


    在Django模型继承中,当一个抽象基类被设计完成后,它会将该基类中定义的Meta内部类以属性的形式提供给子类。另外,如果子类未定义自己的Meta类,那么它就会默认继承抽象基类的Meta类。

    关于Meta类的继承,大致总结如下:

    • 抽象基类中有的元数据属性,如果子模型没有,则子模型直接继承。
    • 抽象基类中有的元数据属性,如果子模型也有,则子模型直接覆盖。
    • 子模型可以额外添加元数据属性。
    • 抽象基类中的abstract=True属性不会被子类继承。
    • 有一些元数据属性(如db_table)对抽象基类是无效的。

    首先,子类如果要设置自己的Meta属性,则必须扩展抽象基类的Meta类。示例代码如下:

    【代码3-16】

    1. 01 from django.db import models
    2. 02
    3. 03 class CommonInfo(models.Model):
    4. 04 # ...
    5. 05 class Meta:
    6. 06 abstract = True
    7. 07 ordering = ['name']
    8. 08
    9. 09 class StudentInfo(CommonInfo):
    10. 10 # ...
    11. 11 class Meta(CommonInfo.Meta): # 注意这里有个继承关系
    12. 12 db_table = 'student_info'
    13. 13 #...
    14. 14 pass

    【代码分析】

    在第03~07行代码中,定义了一个描述通用信息的抽象基类CommonInfo,具体内容说明如下:

    • 在第05~07行代码中,在Meta类中添加了属性“abstract=True”,表明CommonInfo类为抽象基类。

    在第09~14行代码中,定义了一个关于学生信息的子类StudentInfo,具体内容说明如下:

    • 在第11行代码中,定义了自己的Meta类子类,并继承自基类的Meta类CommonInfo.Meta。
    • 在第12行代码中,定义了一个字段属性db_table。注意,该属性就是子类StudentInfo所扩展的属于自己的Meta属性。

    如前文所述,元数据属性db_table对抽象基类无效。首先,对于抽象基类本身而言,是不会创建数据表的;其次,所有子类也不会按照这个元数据属性来设置表名。

    另外,如果想让一个抽象基类的子类也同样成为一个抽象基类,则必须显式地在该子类的Meta类中同样声明一个“abstract=True”属性。示例代码如下:

    【代码3-17】

    1. 01 from django.db import models
    2. 02
    3. 03 class CommonInfo(models.Model):
    4. 04 # ...
    5. 05 class Meta:
    6. 06 abstract = True
    7. 07 ordering = ['name']
    8. 08
    9. 09 class UserInfo(CommonInfo):
    10. 10 # ...
    11. 11 class Meta(CommonInfo.Meta): # 注意这里有个继承关系
    12. 12 abstract = True
    13. 13 ordering = ['username']
    14. 14
    15. 15 class StudentInfo(UserInfo):
    16. 16 # ...
    17. 17 class Meta(UserInfo.Meta): # 注意这里有个继承关系
    18. 18 db_table = 'student_info'
    19. 19 #...
    20. 20 pass

    【代码分析】

    在第03~07行代码中,定义了一个描述通用信息的抽象基类CommonInfo,具体内容说明     如下:

    • 在第05~07行代码中,在Meta类中添加了属性“abstract=True”,表明CommonInfo类为抽象基类。
    • 在第09~13行代码中,定义了一个继承自抽象基类CommonInfo的用户信息子类UserInfo,具体内容说明如下:
    1. 在第11行代码中,定义了自己的Meta类子类,并继承自基类的Meta类CommonInfo.Meta。
    2. 在第12行代码中,在Meta类中添加了属性“abstract=True”,表明子类UserInfo仍为抽象基类。

    在第15~20行代码中,定义了一个继承自抽象基类UserInfo的学生信息子类StudentInfo,具体内容说明如下:

    • 在第17行代码中,定义了自己的Meta类子类,并继承自基类的Meta类UserInfo.Meta。
    • 在第18行代码中,定义了一个字段属性db_table。注意,该属性就是子类StudentInfo所扩展的属于自己的Meta属性。

    最后,基于Python语法继承的工作机制,如果子类继承了多个抽象基类,则默认情况下仅继承第一个列出基类的Meta选项。如果要从多个抽象基类中继承Meta选项,则必须显式地声明Meta继承。示例代码如下:

    【代码3-18】

    1. 01 from django.db import models
    2. 02
    3. 03 class CommonInfo(models.Model):
    4. 04 name = models.CharField(max_length=100)
    5. 05 age = models.PositiveIntegerField()
    6. 06
    7. 07 class Meta:
    8. 08 abstract = True
    9. 09 ordering = ['name']
    10. 10
    11. 11 class Unmanaged(models.Model):
    12. 12 class Meta:
    13. 13 abstract = True
    14. 14 managed = False
    15. 15
    16. 16 class StudentInfo(CommonInfo, Unmanaged):
    17. 17 home_group = models.CharField(max_length=5)
    18. 18
    19. 19 class Meta(CommonInfo.Meta, Unmanaged.Meta):
    20. 20 pass
    21. 21 #...
    22. 22 pass

    【代码分析】

    在第03~09行代码中,定义了第一个描述通用信息的抽象基类CommonInfo,具体内容说明如下:

    • 在第07~09行代码中,在Meta类中添加了属性“abstract=True”,表明CommonInfo类为抽象基类。

    在第11~14行代码中,定义了第二个抽象基类Unmanaged。在第12~14行代码中,在Meta类中添加了属性“abstract=True”,表明Unmanaged类为抽象基类。

    在第16~20行代码中,定义了一个同时继承自抽象基类CommonInfo和Unmanaged的学生信息子类StudentInfo,具体内容说明如下:

    • 在第19行代码中,定义了自己的Meta类子类,并继承自基类的Meta类CommonInfo.Meta和Unmanaged.Meta,该定义方式就是显式地声明Meta类继承。

    本文节选自《Django 5企业级Web应用开发实战(视频教学版)》,获出版社和作者授权发布。

  • 相关阅读:
    webpack优化篇(四十九):使用 webpack 进行图片压缩
    【LeetCode高频SQL50题-基础版】打卡第3天:第16~20题
    游戏引擎分层简介
    Python教程:PyQt5需要学习,哪些知识点??
    一文看懂推荐系统:排序06:粗排三塔模型,性能介于双塔模型和精排模型之间
    [附源码]JAVA毕业设计考研驿站网站(系统+LW)
    Eureka注册中心
    数字电路基础_门电路
    双目视觉(双目相机)
    linux vim 删除多行
  • 原文地址:https://blog.csdn.net/brucexia/article/details/138106240