Django之模型继承

  • Django 的所有基类都必须是django.db.models.Model的子类
  • Djang 共有三种继承方式:
    (1) 抽象基类:基类不会被单独使用(模型不会用于创建任何数据库表),用于保存子模型的一些公共信息
    (2) 多表继承:子类化一个现有模型(可能完全来自另一个应用程序),但每个模型都有自己的数据库表
    (3) 代理模型:仅修改模型的Python级行为,而不以任何方式更改模型字段

抽象基类

  抽象基类声明:像普通模型一样声明,但需要在Meta类中设置abstract=True

from django.db import models

class CommonInfo(models.Model):
    name = models.CharField(max_length=100)
    age = models.PositiveIntegerField()
    # 声明抽象基类
    class Meta:
        abstract = True

class Student(CommonInfo):
    home_group = models.CharField(max_length=5)

  当进行数据库迁移的时候,由于CommonInfo类声明是抽象基类,所以不会生成数据库表或具有管理器,并且无法直接实例化或保存。
  由于 Student 类继承 CommonInfo 类,所以 Student 生成的数据库为Student(name, age, home_group )

Meta 继承
  • 当使用抽象基类时,如果子类没有声明它自己的Meta类,它将继承父类的Meta。
  • 如果子类想要扩展父类的Meta类,可以将其子类化。
  • 当子类继承父类Meta时,会自动设置abstract=False,即抽象基类的子项本身不会自动成为抽象类,如果想声明抽象基类,必须在自己的Meta中声明abstract=True
from django.db import models

class CommonInfo(models.Model):
    name = models.CharField(max_length=100)
    age = models.PositiveIntegerField()
    # 声明抽象基类
    class Meta:
        abstract = True
        ordering = ['name']

class Student(CommonInfo):
    home_group = models.CharField(max_length=5)
    # 继承CommonInfo类的Meta
    class Meta(CommonInfo.Meta):
        db_table = 'student_info'
  • 在抽象基类Meta类中包含一些属性是无意义的,比如说如果在抽象基类中包含db_table则意味着所有子类将使用相同的数据库表

多表继承

  每个模型对应于自己的数据库表,可以单独查询和创建。多表继承使得子模型与父模型之间创建一对一关系OneToOneField

from django.db import models

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

class Restaurant(Place):
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)

其中Restaurant类等价于

class Restaurant(models.Model):
    place_ptr = models.OneToOneField(
        Place, 
        on_delete=models.CASCADE,
        parent_link=True,
    )
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)
Meta与多表继承
  • 一般情况下,子类无法继承父类Meta
  • 在少数有限的情况下,子类从父类继承行为:如果子类没有指定ordering属性或get_latest_by属性,那么它将从父元素继承这些属性。
  • 如果父级有一个排序,并且您不希望子级具有该排序,则可以使用如ordering = []明确禁用父类属性

代理模型

  • 作用:为原始模型创建代理。代理可以创建、删除和更新代理模型的实例,所有数据都将像使用原始(非代理)模型一样保存。不同之处在于,代理可以更改诸如代理中的默认模型排序或默认管理器之类的内容,而无需更改原始的排序。
  • 代理模型声明:像普通模型一样声明,但需要在Meta类中设置proxy=True
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

class MyPerson(Person):
    class Meta:
        proxy = True

    def do_something(self):
        # ...
        pass
  • 代理的意义:仅修改模型的Python级行为,而不以任何方式更改模型字段
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 文章内容大部分参考官方文档,以作者理解叙述Django中模型是你的数据的唯一的,确定的信息源.它包含你所存储数据所...
    da_yu阅读 2,187评论 0赞 3
  • Django 模型定义 Django 模型是使用 Python 代码对数据库中数据的描述,是数据的结构,包含数据的...
    Am3阅读 1,437评论 0赞 2
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,892评论 1赞 32
  • 著名诗人海子有言 “青海湖上,我的孤独如天堂的马匹” 因此我记住了青海湖 仓央嘉措有诗 “纳木措湖等了我多少年,我...
    旅行懒懒阅读 829评论 0赞 1

友情链接更多精彩内容