22.Django三种风格的模型继承

Django三种风格的模型继承

  • 只要继承了model.Model, 就会生成一个新的表,但是,如果在Meta方法中添加abstract=True,就不会产生新的表,而是作为一个基类存放多个表共同拥有的方法和字段等

  • 抽象类继承继承:父类继承自models.Model,但不会在底层数据库中生成相应的数据表,父类的属性列存储在其子类的数据表中。

  • 多表继承:夺标继承的每个模型类都在底层数据库中生成相应的数据表管理数据。

  • 代理模型继承:父类用于在底层数据库中管理数据表;而子类不定义数据列,只定义查询数据集的排列方式等元数据

1. 抽象类(基类,公共类)继承
  • 抽象类,指的是继承了model.Model且没有生成表,而是作为基类或公共类被其他类继承
  • 抽象类继承的作用是在多个表有若干相同的字段时,可以使开发者讲这些字段统一定义在抽象基类中,免于重复定义这些字段。抽象积累的定义通过在模型的Meta中定义属性abstract=True来实现。抽象基类的举例如下:
class Base(models.Model):
    create_time = models.TimeField(auto_now_add=True)
    update_time = models.TimeField(auto_now=True)

    class Meta:
    	# 添加关键字,不会产生新的表
        abstract = True

# 这张表继承了Base,哪怕没有字段create_time和update_time,也同样会展示出来
class CourseType(Base):
    title = models.CharField('课程类别', max_length=16)
    sequence = models.IntegerField('展示顺序', default=18)

    class Meta:
        db_table = 'tb_coursetype'

本列中定义了一个抽象基类Base,用于保存2个公用字段:create_time、update_time 。子类CourseType继承自Base,并分别定义了自己的俩个字段。本列中2个类映射到数据库后,会被定义为1个数据表。

  • 数据表tb_coursetype:有id、title 、sequence 、create_time 、update_time 5个字段

2.多表继承
  • 在多表继承技术中心,无论是父表还是子表都会用数据库中相对应的数据表维护模型数据,父类中字段不会重复地在多个子类的相关数据表中进行定义。从这种意义上讲,多表继承才是真正面向对象的ORM技术。

  • 多表继承的定义不需要特殊的关键字。在Django内部通过在父模型和子模型之间建立一对一关系来实现多表继承技术。如下代码定义了MessageBase及其子类的多表继承版本:

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 Coment(MessageBase):
    level = models.CharField(max_length=1, choices=Levels)

本例在数据库中会实际生成3个数据表。

  • 数据表MessageBase:有id、content、user_name、pub_date等4个字段
  • 数据表Moment:有id、headline等两个字段
  • 数据表Comment:有id、level等两个字段

在对模型的编程过程中,子类仍然可以直接引用父类定义的字段;同时子类可以通过父类对象引用访问父类实例,比如:

# 新建Moment对象,直接在子类中引用父类字段
>>> m1 = Moment(user_name="Tom", headline="hello world") 
>>> m1.content = "reference parent field in subclass"
>>> m1.save()

# 通过父类实例引用父类字段
>>> print m1.messagebase.content
eference parent field in subclass

技巧:在多表继承时,在子类实例中通过小写的父类的名字可以引用父类的实例


3.代理模型继承
  • 前两种继承模型中子类模型都有实际存储数据的作用;而代理模型继承中子类只用于管理父类的数据,而不实际存储数据。代理模型继承通过在子类的Meta中定义proxy=True属性来实现。举例如下:
class Moment(models.Model):
    id = models.AutoField()
    content = models.CharField(max_length=100)
    user_name = models.CharField(max_length=80)
    pub_date = models.DateField()
    headline = models.CharField(max_length=50)


class OrderdMoment(Moment):
    class Meta:
        proxy = True
        ordering = ["-pub_date"]

在本例中定义了父类模型Moment用于存储数据,而后定义了子类模型OrderedMoment用于管理根据pub_date倒序排列的Moment。使用dialing模型继承的原因是子类中新的特性不会影响父类模型及其已有代码的行为。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值