Django实现接口自动化平台(十三)接口模块Interfaces序列化器及视图【持续更新中】

相关文章:

Django实现接口自动化平台(十二)自定义函数模块DebugTalks 序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客

本章是项目的一个分解,查看本章内容时,要结合整体项目代码来看:

python django vue httprunner 实现接口自动化平台(最终版)_python+vue自动化测试平台_做测试的喵酱的博客-CSDN博客

一、Interfaces背景及相关接口

请求方式URI对应action实现功能
GET/Interfaces/.list()查询Interface列表
POST/Interfaces/.create()创建一条数据
GET/Interfaces/{id}/.retrieve()检索一条Interface的详细数据
PUT/Interfaces/{id}/update()更新一条数据中的全部字段
PATCH/Interfaces/{id}/.partial_update()更新一条数据中的部分字段
DELETE/Interfaces/{id}/.destroy()删除一条数据
GET/Interfaces/{id}/configs/查询某个接口的配置信息
POST/Interfaces/{id}/run/运行某个接口下的所有case
GET/Interfaces/{id}/testcases/查询Interface下的case列表

一个项目下,会有多个接口。

一个接口,会有多个case。

1.1 查询Interface列表

GET/Interfaces/.list()查询Interface列表

 接口列表,所有项目的接口都在这个列表里。

1.2 创建接口 Interface

POST/Interfaces/.create()创建一条数据

1.3 编辑更新接口 Interface

PUT/Interfaces/{id}/update()更新一条数据中的全部字段

 

 

二、模型类model

models.py

from django.db import models

from utils.base_models import BaseModel


class Interfaces(BaseModel):
    id = models.AutoField(verbose_name='id主键', primary_key=True, help_text='id主键')
    name = models.CharField('接口名称', max_length=200, unique=True, help_text='接口名称')
    project = models.ForeignKey('projects.Projects', on_delete=models.CASCADE,
                                related_name='interfaces', help_text='所属项目')
    tester = models.CharField('测试人员', max_length=50, help_text='测试人员')
    desc = models.CharField('简要描述', max_length=200, null=True, blank=True, help_text='简要描述')

    class Meta:
        db_table = 'tb_interfaces'
        verbose_name = '接口信息'
        verbose_name_plural = verbose_name
        ordering = ('id',)

    def __str__(self):
        return self.name

这段代码是一个名为 Interfaces 的 Django 模型类,表示接口信息。

该模型类继承了 BaseModel,并定义了以下字段:

  • id:自动生成的自增主键。
  • name:接口名称,是一个字符型字段,最大长度为 200,且必须唯一。
  • project:外键字段,关联到另一个名为 Projects 的模型类,使用级联删除。
  • tester:测试人员,是一个字符型字段,最大长度为 50。
  • desc:简要描述,是一个可选的字符型字段,最大长度为 200,允许为空。

在模型类的 Meta 内部类中,定义了一些元数据:

  • db_table:指定数据库表的名称为 'tb_interfaces'。
  • verbose_name:模型类的可读名称为 '接口信息',用于在管理界面显示。
  • verbose_name_plural:模型类的复数形式可读名称与 verbose_name 相同。
  • ordering:定义默认的排序方式为按照 id 升序排序。

最后,模型类定义了一个 __str__() 方法,返回接口的名称(name 字段值)作为实例的字符串表示,方便在调试和查看对象时使用。

这个模型类表示一个接口信息,包含了接口的名称、所属项目、测试人员和简要描述等字段。

三、序列化器


from rest_framework import serializers

from .models import Interfaces
from projects.models import Projects



class InterfaceModelSerilizer(serializers.ModelSerializer):
    project = serializers.StringRelatedField(label='所属项目名称', help_text='所属项目名称')
    project_id = serializers.PrimaryKeyRelatedField(label='所属项目id', help_text='所属项目id',
                                                    queryset=Projects.objects.all())

    class Meta:
        model = Interfaces
        exclude = ('update_datetime',)
        extra_kwargs = {
            "create_datetime": {
                "read_only": True,
                "format": "%Y年%m月%d日 %H:%M:%S"
            }
        }

    def to_internal_value(self, data):
        result = super().to_internal_value(data)
        result['project'] = result.pop('project_id')
        return result

 

这是一个名为 InterfaceModelSerializer 的 Django REST Framework 序列化器,用于序列化和反序列化接口信息。

该序列化器继承自 ModelSerializer,并定义了以下字段和元数据:

  • project:通过 serializers.StringRelatedField 将关联的项目对象序列化为字符串表示,标签为 "所属项目名称"。
  • project_id:通过 serializers.PrimaryKeyRelatedField 将关联的项目对象序列化为其主键 ID,标签为 "所属项目id",查询集为 Projects.objects.all()。

在模型类中,没有project_id 字段,只有project字段。project字段,获取的值,也不是用户传入的,而是根据表信息查询出来的。所以我们要在序列化器中,手动加入project字段的对应的值。

在 Meta 内部类中,定义了以下属性:

  • model:指定序列化器对应的模型为 Interfaces。
  • exclude:排除不需要被序列化和反序列化的字段,这里排除了 update_datetime 字段。
  • extra_kwargs:用于定义附加的字段参数,这里将 create_datetime 字段设置为只读,并指定日期时间格式为 "%Y年%m月%d日 %H:%M:%S"。

此外,序列化器还重写了 to_internal_value() 方法,通过调用父类的方法获取反序列化后的数据,并将 project_id 字段值赋给 project 字段,以匹配模型类中的命名。

该序列化器实现了序列化和反序列化接口信息,并提供了一些额外的字段参数、数据转换等功能。

这里为什么要重写 to_internal_value()方法:

​​​​​​​result['project'] = result.pop('project_id')

因为在模型类中,没有project_id 字段,只有project字段。

class Interfaces(BaseModel):
    id = models.AutoField(verbose_name='id主键', primary_key=True, help_text='id主键')
    name = models.CharField('接口名称', max_length=200, unique=True, help_text='接口名称')
    project = models.ForeignKey('projects.Projects', on_delete=models.CASCADE,
                                related_name='interfaces', help_text='所属项目')
    tester = models.CharField('测试人员', max_length=50, help_text='测试人员')
    desc = models.CharField('简要描述', max_length=200, null=True, blank=True, help_text='简要描述')

project_id 字段来自

3.1 扩展:重写 to_internal_value() 方法

 3.1.1、ModelSerializer 类介绍:

五、DRF 模型序列化器ModelSerializer_做测试的喵酱的博客-CSDN博客

3.1.2 to_internal_value() 原始方法

继承关系:

 

重写to_internal_value() 方法,to_internal_value() 是继承自Serializer 类。

源码:

    def to_internal_value(self, data):
        """
        Dict of native values <- Dict of primitive datatypes.
        """
        if not isinstance(data, Mapping):
            message = self.error_messages['invalid'].format(
                datatype=type(data).__name__
            )
            raise ValidationError({
                api_settings.NON_FIELD_ERRORS_KEY: [message]
            }, code='invalid')

        ret = OrderedDict()
        errors = OrderedDict()
        fields = self._writable_fields

        for field in fields:
            validate_method = getattr(self, 'validate_' + field.field_name, None)
            primitive_value = field.get_value(data)
            try:
                validated_value = field.run_validation(primitive_value)
                if validate_method is not None:
                    validated_value = validate_method(validated_value)
            except ValidationError as exc:
                errors[field.field_name] = exc.detail
            except DjangoValidationError as exc:
                errors[field.field_name] = get_error_detail(exc)
            except SkipField:
                pass
            else:
                set_value(ret, field.source_attrs, validated_value)

        if errors:
            raise ValidationError(errors)

        return ret

to_internal_value 方法用于将传入的原始数据data转换为内部值,即将外部数data据映射到模型的属性上。

传入的原始数据data:

  • 传入的原始数据可以是一个字典类型(Mapping),即一个键值对组成的数据结构。在这段代码中,通过判断数据类型是否为 Mapping 来确定是否满足传入的要求。如果不是字典类型,就会抛出一个验证错误。字典类型的数据可以是类似 {'key': 'value'} 的形式,其中键和值可以是任意合法的 Python 数据类型。

1、在该方法中,首先判断传入的数据是否是一个字典类型(Mapping)。如果不是字典类型,则抛出一个验证错误,并返回错误信息。然后,创建一个有序字典 ret 用于存储转换后的内部值,以及一个有序字典 errors 用于存储验证过程中的错误信息。

2、接下来,获取可写字段(_writable_fields)列表,并遍历其中的每个字段。对于每个字段,首先尝试获取该字段验证方法(validate_method),然后通过字段的 get_value(data) 方法获取原始数据的值。

3、接着,对原始值进行验证和转换操作,使用字段的 run_validation 方法进行验证,将原始值转换为验证后的值。如果字段定义了验证方法(validate_method),则调用该方法对验证后的值进行进一步处理。

在验证过程中,可能会抛出 ValidationError 或 DjangoValidationError 异常,这表示验证失败。此时,将错误信息保存到 errors 字典中,字段名作为键,错误详情作为值。

如果在验证过程中出现 SkipField 异常,表示跳过该字段的验证操作,直接进入下一个字段。

最后,如果 errors 字典中含有错误信息,则抛出 ValidationError 异常,其中包含了所有字段的验证错误信息。如果没有错误,则返回转换后的内部值 ret。

总结来说,to_internal_value 方法是 Django REST Framework 中用于将外部传入的数据转换为内部值的核心方法,它通过验证和转换操作,将外部数据映射到模型的属性上,并处理了验证过程中可能出现的错误。

to_internal_value() 方法的返回值:

        """
        Dict of native values <- Dict of primitive datatypes.
        """

"Dict of primitive datatypes" 指的是一个字典,其中的值是原始数据类型(primitive datatypes)的数据。常见的原始数据类型包括整数(int)、浮点数(float)、字符串(string)、布尔值(boolean)等。

"Dict of native values" 意味着一个字典,其中的值是原生(native)数据类型的值。在 Python 中,这些原生数据类型与内置数据类型是一致的,如int、float、str、bool等。

因此,"Dict of native values <- Dict of primitive datatypes" 表示将一个字典中的原始数据类型的值转换为对应的原生数据类型的值。这个转换的过程可以通过 Python 的内置功能来完成,例如使用 int()、float()、str()、bool() 等方法来将值转换为相应的原生数据类型。最终的结果将是一个具有相同键但值为原生数据类型的字典。

to_internal_value 方法的返回值通常是一个字典类型(Mapping),表示经过转换后的内部值。在代码中,result 变量就是一个字典,它存储了经过处理后的数据。

3.1.3 重写to_internal_value() 方法

    def to_internal_value(self, data):
        result = super().to_internal_value(data)
        result['project'] = result.pop('project_id')
        return result

在这段代码中,to_internal_value 方法首先调用了父类的 to_internal_value 方法,传入了参数 data。这个方法是继承自父类的,默认的实现会将传入的数据转换为内部值。

然后,result['project'] = result.pop('project_id') 这一行代码将字典中键为 'project_id' 的值取出,并以 'project' 作为键添加到 result 字典中。同时,result.pop('project_id') 会将原字典中键为 'project_id' 的键值对删除。

最后,返回经过处理后的 result 字典。

这段代码的作用是将传入的数据中的 'project_id' 键值对提取出来,并将其改名为 'project',然后返回处理后的字典。这样可以实现对数据的字段重命名操作。

四、视图

class InterfaceViewSet(RunMixin, viewsets.ModelViewSet):
    queryset = Interfaces.objects.all()
    serializer_class = serializers.InterfaceModelSerilizer
    permission_classes = [permissions.IsAuthenticated]

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/39378.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华润燃气牵手腾讯云 数字技术助力燃气行业高质量发展

7月13日&#xff0c;华润燃气与腾讯云正式签署战略合作协议。双方将充分发挥各自优势&#xff0c;探索AI大模型在燃气行业的深度应用&#xff0c;并深耕分布式计算、连接和客户运营等领域&#xff0c;不断提升燃气民生服务的效率、质量&#xff0c;共同推动行业数字化转型和高质…

巧妙使用 CSS 渐变来实现波浪动画

目录 一、波浪的原理 二、曲面的绘制 三、波浪动画 四、文字波浪动画 五、总结一下 参考资料 之前看到coco[1]的这样一篇文章&#xff1a;纯 CSS 实现波浪效果&#xff01;[2]&#xff0c;非常巧妙&#xff0c;通过改变border-radius和不断旋转实现的波浪效果&#xff0c…

初探KVM虚拟化技术:新手指南

首先了解一下虚拟化的概念 虚拟化是指对资源的逻辑抽象、隔离、再分配、管理的一个过程&#xff0c;通常对虚拟化的理解有广义狭义之分。广义包括平台虚拟化、应用程序虚拟化、存储虚拟化、网络虚拟化、设备虚拟化等等。狭义的虚拟化专门指计算机上模拟运行多个操作系统平台。…

面试中关于自动化测试的认识

目录 一、什么是自动化测试&#xff0c;自动化测试的优势是什么&#xff1f; 二、什么样的项目比较适合做自动化测试&#xff0c;什么样的不适合做自动化测试&#xff1f; 三、在制定自动化测试计划的时候一般要考虑哪些点&#xff1f; 四、编写自动化脚本时的一些规范&…

C#图片处理

查找图片所在位置 原理&#xff1a;使用OpenCvSharp对比查找小图片在大图片上的位置 private static System.Drawing.Point Find(Mat BackGround, Mat Identify, double threshold 0.8) {using (Mat res new Mat(BackGround.Rows - Identify.Rows 1, BackGround.Cols - Iden…

WEB:shrine

背景知识 了解Flask SSIT模板注入 题目 进行代码审计 import flask import osapp flask.Flask(__name__) /*创建了flask包下的Flask类的对象&#xff0c;name是一个适用于多数情况的快捷方式。有了这个参数&#xff0c;Flask才知道在哪里可以找到模板和静态文件*/app.confi…

【Fiddler】Fiddler实现mock测试(模拟接口数据)

软件接口测试过程中&#xff0c;经常会遇后端接口还没有开发完成&#xff0c;领导就让先介入测试&#xff0c;然后缩短项目时间&#xff0c;有的人肯定会懵&#xff0c;接口还没开发好&#xff0c;怎么介入测试&#xff0c;其实这就涉及到了我们要说的mock了。 一、mock原理 m…

小程序:页面跳转闪屏

自己的笔记&#xff0c;随手记录。扛精走开。 1、问题描述 进入页面&#xff0c;是一个组件&#xff0c;通过路由传参判断是由哪个页面进入&#xff0c;不同的页面拿的已选值不一样&#xff0c;需要回显值&#xff0c;在编辑数据。此时会出现一个问题&#xff0c;A页面中进来…

微信小程序——字符串截取

indexOf() &#xff1a; 判断一个字符是否在字符串 中 存在&#xff0c;如果存在返回该元素或字符第一次出现 的 位置 的 索引&#xff0c;不存在返回-1。 lastIndexOf() &#xff1a; 返回一个指定的字符串值最后出现的位置&#xff0c;在一个字符串中的指定位置从后向前搜索。…

【NLP】多头注意力概念(02)

接上文: 【NLP】多头注意力概念(01) 五、计算注意力 将 Q、K 和 V 拆分为它们的头部后,现在可以计算 Q 和 K 的缩放点积。上面的等式表明,第一步是执行张量乘法。但是,必须先转置 K。 展望未来,每个张量的seq_length形状将通过其各自的张量来识别,以确保清晰…

⚡【C语言趣味教程】(3) 浮点类型:单精度浮点数 | 双精度浮点型 | IEEE754 标准 | 介绍雷神之锤 III 源码中的平方根倒数速算法 | 浮点数类型的表达方式

&#x1f517; 《C语言趣味教程》&#x1f448; 猛戳订阅&#xff01;&#xff01;&#xff01; ​—— 热门专栏《维生素C语言》的重制版 —— &#x1f4ad; 写在前面&#xff1a;这是一套 C 语言趣味教学专栏&#xff0c;目前正在火热连载中&#xff0c;欢迎猛戳订阅&#…

Linux Ubuntu安装RabbitMQ服务

文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基…

使用qemu创建ubuntu-base文件系统,并安装PM相关内核模块

目录 一、配置镜像二、使用qemu模拟nvdimm&#xff08;安装PM相关内核模块&#xff09;运行记录 遇到的一些问题1、ext4文件系统损坏问题&#xff1a;系统启动时&#xff0c;遇到ext4的报错信息解决办法&#xff1a;2、内核模块未成功加载3、qemu报错4、主机终端无法正常打开5、…

【Spring 】执行流程解析:了解Bean的作用域及生命周期

哈喽&#xff0c;哈喽&#xff0c;大家好~ 我是你们的老朋友&#xff1a;保护小周ღ 今天给大家带来的是 Spring 项目的执行流程解析 和 Bean 对象的6 种作用域以及生命周期&#xff0c;本文将为大家讲解&#xff0c;一起来看看叭~ 本期收录于博主的专栏&#xff1a;JavaEE_保…

数据库应用:MySQL高级语句(一)

目录 一、理论 1.常用查询 2.函数 3.进阶查询 二、实验 1.普通查询 2.函数 3.进阶查询 三、问题 1.MySQL || 运算符不生效 四、总结 一、理论 1.常用查询 常用查询包括&#xff1a;增、删、改、查&#xff1b; 对 MySQL 数据库的查询&#xff0c;除了基本的查询外…

网络安全能力成熟度模型介绍

一、概述 经过多年网络安全工作&#xff0c;一直缺乏网络安全的整体视角&#xff0c;网络安全的全貌到底是什么&#xff0c;一直挺迷惑的。目前网络安全的分类和厂家非常多&#xff0c;而且每年还会冒出来不少新的产品。但这些产品感觉还是像盲人摸象&#xff0c;只看到网络安…

09_SPI-Flash 页写实验

09_SPI-Flash 页写实验 1. 实验目标2. 操作时序3. 模块框图3.1 顶层模块3.2 页写模块 4. 波形图5. RTL5.1 flash_pp_ctrl5.2 spi_flash_pp 6. Testbench6.1 tb_flash_pp_ctrl6.2 tb_spi_flash_pp 1. 实验目标 使用页写指令&#xff0c;向 Flash 中写入 N 字节数据&#xff0c;…

Linux查看某进程所部署的目录路径

1.首先查看系统中正在跑的进程都有什么 ps -ef 2.然后通过抓取你要看的进程名&#xff0c;比如哪些服务 ps -ef | grep xxxxx(服务名) Linux在启动一个进程时&#xff0c;系统会在 /proc 下创建一个以PID命名的文件夹&#xff1b; 在该文件夹下会有我们的进程的信息&#…

高时空分辨率、高精度一体化预测技术之风、光、水能源自动化预测教程

详情点击链接&#xff1a;高时空分辨率、高精度一体化预测技术之风、光、水能源自动化预测 第一&#xff1a;预测平台及安装 一、高精度气象预测基础 综合气象观测数值模拟模式&#xff1b; 全球预测模式、中尺度数值模式&#xff1b; 二、自动化预测平台 Linux系统 Crontab…

redis 相关

redis相关面试题 redis支持哪几种数据形式&#xff1f; String,hash,set,zset,list redis主要消费什么物理资源&#xff1f; 内存&#xff0c;key-value的形式&#xff0c; redis 具有快速和数据持久化的特征&#xff0c;如果不将数据放在内存中&#xff0c;磁盘 I/O 速度为严…
最新文章