测试平台——项目模块模型类设计

这里写目录标题

  • 一、项目应用
    • 1、项目包含接口:
    • 2、创建子应用
    • 3、项目模块设计
      • a、模型类设计
      • b、序列化器类设计
      • c、视图类设计
    • 4、接口模块设计
      • a、模型类设计
      • b、序列化器类设计
      • c、视图类设计
    • 5、环境模块设计
    • 6、DRF中的通用过滤
      • 6.1、设置过滤器后端

一、项目应用

1、项目包含接口:

  • 项目管理接口
  • 接口管理接口
  • 环境管理接口

2、创建子应用

python manage.py startapp projects

3、项目模块设计

a、模型类设计

from django.db import models

# Create your models here.
class Project(models.Model):
    """项目表"""
    name = models.CharField(max_length=50, help_text='项目名称', verbose_name='项目名')
    leader = models.CharField(max_length=50, help_text='负责人', verbose_name='负责人', default='')
    create_time = models.DateTimeField(verbose_name='创建时间', help_text='创建时间', auto_now_add=True)

    class Meta:
        db_table = 'tb_project'
        verbose_name = '项目表'
        verbose_name_plural = verbose_name

    def _str__(self):
        return self.name

b、序列化器类设计

from rest_framework import serializers
from rest_framework.serializers import ModelSerializer

class ProjectSerializer(ModelSerializer):
    class Meta:
        model = Project
        fields = ['id', 'name', 'leader', 'create_time']

c、视图类设计

class ProjectViewSet(ModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerializer

获取项目的详情数据
需要展示字段:执行环境、执行场景、测试计划、接口数量、定时任务、执行记录

测试平台——项目模块模型类设计_第1张图片
方法一:需要重写retrieve方法

class ProjectViewSet(ModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerializer

    # permission_classes = [IsAuthenticated]

    def retrieve(self, request, *args, **kwargs):
        response = super().retrieve(self, request, *args, **kwargs)
        obj = self.get_object()
        response.data['info'] = [
            {'name': '执行环境', 'value': TestEnv.objects.filter(project_id=obj.id).count()},
            {'name': '执行场景', 'value': TestScene.objects.filter(project_id=obj.id).count()},
            {'name': '测试计划', 'value': TestPlan.objects.filter(project_id=obj.id).count()},
            {'name': '接口数量', 'value': Interface.objects.filter(project_id=obj.id).count()},
            {'name': '定时任务', 'value': 0},  # todo 定时任务未开发
            {'name': '执行记录', 'value': Record.objects.filter(plan__project=obj).count()}
        ]
        return response

方法二:模型类中定义新的字段(重点)

模型类

class Project(models.Model):
    """项目表"""
    name = models.CharField(max_length=50, unique=True, help_text='项目名称', verbose_name='项目名')
    leader = models.CharField(max_length=50, help_text='负责人', verbose_name='负责人', default='')
    create_time = models.DateTimeField(verbose_name='创建时间', help_text='创建时间', auto_now_add=True)

    class Meta:
        db_table = 'tb_project'
        verbose_name = '项目表'
        verbose_name_plural = verbose_name

    def _str__(self):
        return self.name

    def info(self):
        return [
            {'name': '执行环境', 'value': self.test_envs.count()},
            {'name': '执行场景', 'value': self.test_scenes.count()},
            {'name': '测试计划', 'value': self.test_plans.count()},
            {'name': '接口数量', 'value': self.interfaces.count()},
            {'name': '定时任务', 'value': 0},       #todo 定时任务未开发
            {'name': '执行记录', 'value': Record.objects.filter(plan__project=self).count()}
        ]

序列化器设计

class ProjectSerializer(ModelSerializer):
    class Meta:
        model = Project
        fields = ['id', 'name', 'leader', 'create_time', 'info', 'bugs']

视图设计

class ProjectViewSet(ModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerializer

4、接口模块设计

a、模型类设计

class Interface(models.Model):
    """接口表"""
    CHOICES = [
        ('1', '项目接口'),
        ('2', '外部接口')]

    project = models.ForeignKey('Project',
                                on_delete=models.CASCADE,
                                help_text='项目id',
                                verbose_name='项目id',
                                related_name='interfaces')
    name = models.CharField(max_length=50, help_text='接口名称', verbose_name='接口名称')
    url = models.CharField(max_length=200, help_text='接口路径', verbose_name='接口路径')
    method = models.CharField(max_length=50, help_text='请求方法', verbose_name='请求方法')
    type = models.CharField(verbose_name='接口类型',
                            help_text='接口类型',
                            max_length=40,
                            choices=CHOICES,
                            default='1')

    # 扩展,接口的说明,接口字段的参数

    def __str__(self):
        return self.url

    class Meta:
        db_table = 'tb_interface'
        verbose_name = '接口表'
        verbose_name_plural = verbose_name

b、序列化器类设计

class NestTestStepSerializer(ModelSerializer):
    """嵌套测试步骤序列化器"""

    class Meta:
        model = TestStep
        fields = ['id', 'title']


class InterfaceSerializer(ModelSerializer):
    steps = NestTestStepSerializer(many=True, read_only=True, source='teststep_set')

    class Meta:
        model = Interface
        fields = '__all__'

    def validate(self, attrs):
        url = attrs.get('url')
        type_ = attrs.get('type')
        if type_ == '2':
            if not url.startswith('http'):
                raise serializers.ValidationError('外部接口的url需要完整的url,必须以http或者https开头')
        return attrs

获取接口的列表信息时:还需要将接口的下用例信息获取出来

c、视图类设计

5、环境模块设计

class TestEnv(models.Model):
    """测试坏境表"""
    name = models.CharField(max_length=150, help_text='环境名称', verbose_name='环境名称')
    project = models.ForeignKey(Project,
                                on_delete=models.CASCADE,
                                help_text='项目id',
                                verbose_name='项目id')
    global_variable = models.JSONField(help_text='全局变量',
                                       verbose_name='全局变量',
                                       default=dict,
                                       null=True)
    debug_global_variable = models.JSONField(help_text='debug模式全局变量',
                                             verbose_name="debug模式全局变量",
                                             default=dict,
                                             null=True)
    db = models.JSONField(help_text='数据库配置',
                          verbose_name='数据库配置',
                          default=list,
                          null=True,blank=True)
    host = models.CharField(help_text='base_url地址',
                            verbose_name='base_url地址',
                            max_length=100,
                            null=True,blank=True)
    headers = models.JSONField(help_text='请求头',
                               verbose_name='请求头',
                               default=dict,
                               null=True, blank=True)
    global_func = models.TextField(help_text='全局工具函数',
                                   verbose_name='全局工具函数',
                                   default=open('./utils/global_func.py', 'r',
                                                encoding='utf-8').read(),
                                   null=True,blank=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'tb_testenv'
        verbose_name = '接口表'
        verbose_name_plural = verbose_name

6、DRF中的通用过滤

除了能够覆盖默认查询集之外,REST 框架还包括对通用过滤后端的支持,允许您轻松构建复杂的搜索和过滤器。

6.1、设置过滤器后端

可以使用设置全局设置默认过滤器后端DEFAULT_FILTER_BACKENDS。例如。

a、要使用DjangoFilterBackend,请先安装django-filter

pip install django-filter

注意djoango-filter仅支持:
● Python: 3.6,3.7,3.8
● Django: 2.2, 3.1,3.2
● DRF: 3.10+

b、注册

INSTALLED_APPS = [
    ...
    'django_filters',
	...
]

c、配置

REST_FRAMEWORK = {
	...
	...
    # 过滤
    'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
}

d、使用
在后端类视图或者视图集中添加filterset_fields属性即可实现指定字段过滤,例如改写环境管理视图集
如下:

class EnvViewSet(ModelViewSet):
    queryset = TestEnv.objects.all()
    serializer_class = EnvSerializer
    filterset_fields = ['name','project']

不需要在复写get_queryset方法手动过滤,就可以通过url/test_envs/?project=1访问过滤数据了。
注意:当使用外键字段过滤时,如果级联模式是删除,则使用不存在的数据过滤会返回400响应。例如上面的
视图如果使用不存在的项目id过滤返回结果如下:

http://127.0.0.1:8000/test_envs?project=2

测试平台——项目模块模型类设计_第2张图片

你可能感兴趣的:(#,测试效能平台(二),django,python,后端)