当前位置:   article > 正文

Django 模型的继承_django继承

django继承

项目管理

到目前为止,都是属于httprunner中的用例部分,针对核心功能进行的开发工作,要把平台做成一个用户可以使用的程度还需要些额外的功能,比如项目管理,用户管理等。

首先考虑需要增加的数据模型,项目管理需要项目,模块,和测试环境等相关数据,同时原有模型需要增加一些额外的通用字段,如增加时间,更新时间等。

模型关联关系

首先确立模型的关联关系

在这里插入图片描述

用例和项目之间的关联可以直接通过config,因为config是套件和用例的扩展,相当于用例和套件本身。

模块的包管理

在我们使用 python manage.py startapp xxx 命令创建新的应用时,Django会自动帮我们建立一个应用的基本文件组织结构,其中就包括一个 models.py 文件。通常,我们把当前应用的模型都编写在这个文件里,但是如果你的模型很多,那么将单独的 models.py 文件分割成一些独立的文件是个更好的做法。

首先,我们需要在应用中新建一个叫做 models 的包,包下自动创建了一个__init__.py文件,该文件是用于确立包的身份,建同名的目的是为了其他引用原model.py文件的模块中代码不需发生更改。

新增一个hr3.py文件,将 models.py 文件中的代码复制到hr3.py文件中,然后删除 models.py 文件

最后在 __init__.py 文件中导入所有的模型。

from .hr3 import Step,Case,Config,Request
  • 1

要显式明确地导入每一个模型,而不要使用 from .models import * 的方式,这样不会混淆命名空间,让代码更可读,更容易被分析工具使用。

最终的模型结构

其中hr3.py存放所有核心数据模型,mgr.py 存放所有项目管理相关(项目和环境数据)模型

mgr.py

# 存放所有项目管理相关模型

from django.db import models

# 定义项目 类
class Project(models.Model):
    Pro_Status = (
        ('developing','开发中'),
        ('operating','维护中'),
        ('stable','稳定运行中'),
        )
    name = models.CharField(max_length=32,unique=True,verbose_name='项目名称')
    status = models.CharField(max_length=32,choices=Pro_Status,default='stable',verbose_name='项目状态')
    version = models.CharField(max_length=32,default='V1.0',verbose_name='版本')

    def __str__(self):
        return self.name    # 以 项目名称 对外展示

    # 模型元类
    class Meta:
        db_table = 'Project'  # 如果不设置,默认的名称是 app名_模型名
        ordering = ['id']  # 根据id排序(默认为顺序排序)
        verbose_name = '项目表'  # 表的对外显示名称


# 定义 测试环境 类
class Enviroment(models.Model):
    # 服务器类型选项
    service_type = (
        (0,'web服务器'),
        (1,'数据库服务器'),
        (2,'文件存储服务器'),
    )
    # 服务器操作系统类型选项
    service_os = (
        (0, 'Windows'),
        (1, 'CentOS'),
        (2, 'Ubuntu'),
        (3, 'Debian'),
    )
    # 服务器状态类型选项
    service_status = (
        (0, '未激活'),
        (1, '使用中'),
        (2, '已过期'),
    )
    project = models.ForeignKey(Project,on_delete=models.CASCADE,verbose_name='所属项目')
    # django-ORM框架提供 GenericIPAddressField 专门存储ip类型信息,对入参ip格式会有校验
    ip = models.GenericIPAddressField(default='127.0.0.1',verbose_name='IP地址')
    # PositiveSmallIntegerField 正整数类型
    port = models.PositiveSmallIntegerField(default=80,verbose_name='端口号')
    category = models.SmallIntegerField(choices=service_type,default=0,verbose_name='服务器类型')
    os = models.SmallIntegerField(choices=service_os,default=1,verbose_name='服务器操作系统')
    status = models.SmallIntegerField(choices=service_status,default=0,verbose_name='服务器状态')

    def __str__(self):
        return self.ip+self.port

    # 模型元类
    class Meta:
        db_table = 'Enviroment'  # 如果不设置,默认的名称是 app名_模型名
        ordering = ['id']  # 根据id排序(默认为顺序排序)
        verbose_name = '测试环境表'  # 表的对外显示名称
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

模型的继承

一般在实际项目中,数据模型除了业务字段以外,还需要有一些通用字段,如创建时间,更新时间,创建者,更新者等,这些字段如果在每个模型都定义的话,冗余度很高,而且维护起来不方便。

此时,我们可以用一个抽象模型类来存放这些字段,然后其他模型继承该抽象模型类即可。

models 包下创建了一个base.py文件,定义一个抽象模型 CommonInfo

# 公共模型

from django.db import models

class CommonInfo(models.Model):
    # 公共字段部分: 创建时间、更新时间、描述
    create_time = models.DateTimeField(auto_now_add=True,verbose_name='创建时间')
    # auto_now_add 第一次创建数据时自动添加当前时间
    update_time = models.DateTimeField(auto_now=True,verbose_name='更新时间')
    # auto_now 每次更新数据时自动添加当前时间
    desc = models.TextField(null=True,blank=True,verbose_name='描述')

    def __str__(self):
        # 判断当前数据对象是否有name属性,如果有,返回name,如果没有,返回描述
        if hasattr(self,'name'):    # hasattr 是Python中是反射的一种用法
            return self.name
        else:
            return self.desc


    class Meta:
        abstract =True  # 定义抽象表,不会创建数据库表
        ordering = ['id']  # 根据id排序(默认为顺序排序)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

由于在元类中定义了abstract = True ,抽象模型在同步数据库的时候并不会创建表,子类只会继承其字段和方法

另外元类除了abstract = True不会继承,其他都会继承,若想把子类也设置为抽象模型,必须显示在元类中设置abstract = True

mgr.py 中的模型为例,子类继承抽象父类:

mgr.py

# 存放所有项目管理相关模型

from django.db import models
from .base import CommonInfo

# 定义项目 类
class Project(CommonInfo):
    Pro_Status = (
        ('developing','开发中'),
        ('operating','维护中'),
        ('stable','稳定运行中'),
        )
    name = models.CharField(max_length=32,unique=True,verbose_name='项目名称')
    status = models.CharField(max_length=32,choices=Pro_Status,default='stable',verbose_name='项目状态')
    version = models.CharField(max_length=32,default='V1.0',verbose_name='版本')

    # 模型元类
    class Meta(CommonInfo.Meta): # 元类也需要显示继承父类的元类才会生效
        db_table = 'Project'  # 如果不设置,默认的名称是 app名_模型名
        verbose_name = '项目表'  # 表的对外显示名称


# 定义 测试环境 类
class Enviroment(CommonInfo):
    # 服务器类型选项
    service_type = (
        (0,'web服务器'),
        (1,'数据库服务器'),
        (2,'文件存储服务器'),
    )
    # 服务器操作系统类型选项
    service_os = (
        (0, 'Windows'),
        (1, 'CentOS'),
        (2, 'Ubuntu'),
        (3, 'Debian'),
    )
    # 服务器状态类型选项
    service_status = (
        (0, '未激活'),
        (1, '使用中'),
        (2, '已过期'),
    )
    project = models.ForeignKey(Project,on_delete=models.CASCADE,verbose_name='所属项目')
    # django-ORM框架提供 GenericIPAddressField 专门存储ip类型信息,对入参ip格式会有校验
    ip = models.GenericIPAddressField(default='127.0.0.1',verbose_name='IP地址')
    # PositiveSmallIntegerField 正整数类型
    port = models.PositiveSmallIntegerField(default=80,verbose_name='端口号')
    category = models.SmallIntegerField(choices=service_type,default=0,verbose_name='服务器类型')
    os = models.SmallIntegerField(choices=service_os,default=1,verbose_name='服务器操作系统')
    status = models.SmallIntegerField(choices=service_status,default=0,verbose_name='服务器状态')

    def __str__(self):
        return self.ip+self.port

    # 模型元类
    class Meta(CommonInfo.Meta):
        db_table = 'Enviroment'  # 如果不设置,默认的名称是 app名_模型名
        ordering = ['-id']  # 根据id倒序排序
        verbose_name = '测试环境表'  # 表的对外显示名称
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

Project类和Enviroment类都需要继承CommonInfo抽象类,且元类Meta也需要继承CommonInfo中的Meta元类,但如果有相同的字段,会被覆盖,比如Enviroment类中排序ordering是根据 id 倒序排序

类似的,对hr3.py文件也可进行抽象类的继承

models 包下的 __init__.py 文件中导入所有的模型

from .hr3 import Step,Case,Config,Request
from .mgr import Enviroment,Project
  • 1
  • 2

将修改同步至数据库

python manage.py makemigrations
python manage.py migrate
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/769123
推荐阅读
相关标签
  

闽ICP备14008679号