Django JSONField类型操作解析

这篇具有很好参考价值的文章主要介绍了Django JSONField类型操作解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

接口测试平台核心以Httprunner为接口用例运行框架,要将用例的数据持久化到数据库中,方便读取修改与存储,则需要按照 yaml/json 的数据结构来设计数据库。

数据库模型关系图的总体结构

Django JSONField类型操作解析

执行命令 django-admin startproject AutoTpsite 创建一个项目名为 AutoTpsite 的Django项目

再执行python manage.py startapp sqtp命令创建一个名为 sqtp的应用

模型代码设计

其中,request,step和config参考HR对应部分的字段,由于其中会出现很多嵌套字段,所以1层的字段就用json数据类型来代替。

models.py下创建模型

配置config部分

class Config(models.Model):
    name = models.CharField('测试用例名称',max_length=128)
    base_url = models.CharField('IP/域名',max_length=256,null=True,blank=True) #可为空或者空白
    variables = models.JSONField('变量',null=True)
    parameters = models.JSONField('参数',null=True)
    export = models.JSONField('用例返回值',null=True)
    verify = models.BooleanField('https校验',default=False)

    def __str__(self):
        return self.name
        # 以 测试用例名称 对外展示

通过 models.JSONField 可指定此字段为存储类型为JSON格式。null=True 表示此字段可以为空,这个NULL指的是SQL NULL,如果想存储为JsonNULL,则可以使用 Value('null') 来实现

用例Case部分

class Case(models.Model):
    # 一对一关系指向配置config 关联约束选择  DO_NOTHING 不做删除,保留
    config = models.OneToOneField(Config,on_delete=models.DO_NOTHING)
    # 用例文件路径,用于后续数据的导出
    file_path = models.CharField('用例文件路径',max_length=1000,default='demo_case.json')

    def __str__(self):
        return self.config.name
        # 以 config名称(测试用例名称) 对外展示

测试用例与配置config的对应关系为 一对一 ,通过 models.OneToOneField 配置关联约束

测试步骤Step部分

class Step(models.Model):
    # related_name 反向查询名称 同个模型中,两个字段关联同1个模型,必须指定related_name ,且名字不能相同

    # 属于哪条测试用例,属于的用例被删除了,测试步骤也就没有存在的必要了 关联约束选择 CASCADE级联删除
    belong_case = models.ForeignKey(Case,on_delete=models.CASCADE,related_name='teststeps')
    # 引用的哪条测试用例,引用的用例被删除了,测试步骤可能还需要存在 关联约束选择  DO_NOTHING 不做删除,保留,或 SET_NULL 允许为null
    linked_case = models.ForeignKey(Case,on_delete=models.SET_NULL,null=True,related_name='linked_steps')

    name = models.CharField('测试步骤名称', max_length=128)
    variables = models.JSONField('变量', null=True)
    extract = models.JSONField('请求返回值', null=True)
    validate = models.JSONField('校验项', null=True)
    setup_hooks = models.JSONField('初始化', null=True)
    teardown_hooks = models.JSONField('清除', null=True)

    def __str__(self):
        return self.name
        # 以 测试步骤名称 对外展示

Httprunner测试框架中,测试步骤可以属于某条测试用例,一条测试用例中可能会存在多条测试用例;而测试步骤也能引用其他测试用例。

在数据存储的观点来看,测试步骤与测试用例之间的关系为 多对一 ,通过外键 ForeignKey 进行关联,但在模型的设计中,需要将这两种关联关系区分开来,所以需要有两个字段。两个字段关联同1个模型,这里需要通过related_name 反向查询名称进行区分,且名字不能相同

请求Request部分

class Request(models.Model):
    # 一对一关系指向测试步骤Step 关联约束选择 CASCADE级联删除
    step = models.OneToOneField(Step,on_delete=models.CASCADE,null=True)
    # method可选字段,二维元组
    method_choices = (
        (0, 'GET'),  # 参数1:保存在数据库中的值,参数2:对外显示的值
        (1, 'POST'),
        (2, 'PUT'),
        (3, 'DELETE'),
    )
    method = models.SmallIntegerField('请求方法',choices=method_choices,default=0)
    url = models.CharField('请求路径', default='/', max_length=1000)
    params = models.JSONField('url参数', null=True)
    headers = models.JSONField('请求头', null=True)
    cookies = models.JSONField('Cookies', null=True)
    data = models.JSONField('data参数', null=True)
    json = models.JSONField('json参数', null=True)
    
    def __str__(self):
        return self.url
        # 以 请求路径 对外展示

http请求方式通常有GET、POST、PUT、DELETE,像这种数据库存储字段的值有限定内容的时候,可以先创建一个二维元组,参数1表示保存在数据库中的值,参数2表示对外显示的值,通过choices指定创建的二维元素。数据库中只需要存0、1、2、3这些数字即可,不需要设定为CharField类型,设定为SmallIntegerField即可,这种方式可以减少数据存储的压力。

正向查询与反向查询解析

在1对1,1对多,多对多关系中都存在正向查询和反向查询,模型查询其关联的项目叫做正向查询

如多对一关系中,正向查询是多方查询单方,因为外键是定义在多方,通过模型对象的外键 即modelObj.foreigner 进行查询则为正向查询;反向查询是单方查找多方,通过模型对象的外键模型的小写_setmodelObj.foreigner_set 进行查询

在tests.py文件下进行测试

from django.test import TestCase

# Create your tests here.

from sqtp.models import Case,Config,Step,Request

class TestRelatedQuery(TestCase):

    def setUp(self) -> None:
       self.config1 = Config.objects.create(name='用例1',base_url='http://127.0.0.1:8080/')
       self.config2 = Config.objects.create(name='用例2',base_url='http://127.0.0.1:8888/')
       self.case1 = Case.objects.create(config=self.config1)
       self.case2 = Case.objects.create(config=self.config2)

    def test_steps_query(self):
       step1 = Step.objects.create(belong_case=self.case1, name='步骤1') # 步骤1关联用例1
       step1.linked_case = self.case2 # 步骤1引用用例1
       step1.save()
       step2 = Step.objects.create(belong_case=self.case2, name='步骤2') # 步骤2关联用例2

       # 正向查询
       print('===========正向查询===========')
       print(step1.belong_case) #查看step1所属用例
       print(step1.linked_case)  # 查看step1引用的用例
       print(step2.belong_case) #查看step2所属的用例

       # 反向查询
       print('===========反向查询===========')
       # related_name代替 step_set
       print(self.case1.teststeps.all()) # 查询用例1下面有哪些步骤
       print(self.case2.linked_steps.all()) # 查询用例2被哪些步骤引用

输出结果

===========正向查询===========
用例1
用例2
用例2
===========反向查询===========
<QuerySet [<Step: 步骤1>]>
<QuerySet [<Step: 步骤1>]>

外键在 Step模型 中定义,与 Case模型 进行关联,而 Case模型 与 Config模型 一对一关联。

通过Step查询关联的用例,则是正向查询

通过用例查询步骤,则是属于反向查询,正常情况下要通过模型小写_set(即step_set)进行查询,但是在Step模型 中比较特殊,两个字段关联同1个模型,所以需要用 related_name 代替 step_set

Json字段操作解析

模型中大部分字段都是json类型(Django模型 JSONField类型)存储,以Request(请求信息)模型为例,操作增删改查

在tests.py文件下进行测试

新增
from django.test import TestCase

# Create your tests here.

from sqtp.models import Case, Config, Step, Request
from django.db.models import Value

class TestJsonField(TestCase):

    def setUp(self) -> None:
        print('====================新增数据======================')
        req1 = Request.objects.create(method=1,url='/mgr/student/',data={"name":"小明","age":16,"address":"广东广州","school":{"PrimarySchool":"实验小学","SecondarySchool":"第一中学"}})
        req2 = Request.objects.create(method=0,url='/api/teacher/',data={"name":"小王老师","courses":"英语","address":"广东深圳"})
        req3 = Request.objects.create(method=3,url='/api/delete/',data={"id":105,"display_idx":1})
        req = Request.objects.all()
        print(req)

执行命令python manage.py test sqtp.tests.TestJsonField进行测试

通过objects.create()新增数据,通过Request.objects.all()查询数据,输出结果

====================新增数据======================
<QuerySet [<Request: /mgr/student/>, <Request: /api/teacher/>, <Request: /api/delete/>]>
查询
Json条件查询
class TestJsonField(TestCase):

    def setUp(self) -> None:
        print('====================新增数据======================')
        req1 = Request.objects.create(method=1,url='/mgr/student/',data={"name":"小明","age":16,"address":"广东广州","school":{"PrimarySchool":"实验小学","SecondarySchool":"第一中学"}})
        req2 = Request.objects.create(method=0,url='/api/teacher/',data={"name":"小王老师","courses":"英语","address":"广东深圳"})
        req3 = Request.objects.create(method=3,url='/api/delete/',data={"id":105,"display_idx":1})
        req = Request.objects.all()
        print(req)


    def test_json_01(self):
        print('====================查询数据======================')
        req1 = Request.objects.all().first()
        print(req1)
        print(req1.data)  # 查询data数据内容

        print('====================json条件查询======================')
        req2 = Request.objects.filter(data__age=16)
        print(req2)
        req3 = Request.objects.filter(data__school__PrimarySchool="实验小学")
        print(req3)
        

通过Request.objects.all().first()查询出第一条数据

若想要根据json里的内容筛选数据,可以根据字段名__参数名(注意是双下划线)查询json字段里的内容,存在多层嵌套,依旧可以查询成功

输出结果

====================查询数据======================
/mgr/student/
{'name': '小明', 'age': 16, 'address': '广东广州', 'school': {'PrimarySchool': '实验小学', 'SecondarySchool': '第一中学'}}
====================json条件查询======================
<QuerySet [<Request: /mgr/student/>]>
<QuerySet [<Request: /mgr/student/>]>
字段条件查询

字段查询是指如何指定 SQL WHERE子句 的内容。它们用作 QuerySet 的 filter()、exclude() 和 get() 方法的关键字参数。 其基本格式是:field__lookuptype=value(注意其中是双下划线),默认查找类型为exact(精确匹配)。

Django的数据库API支持20多种查询类型:

字段名 说明
exact 精确匹配
iexact 不区分大小写的精确匹配
contains 包含匹配
icontains 不区分大小写的包含匹配
in 在…之内的匹配
gt 大于
gte 大于等于
lt 小于
lte 小于等于
startswith 从开头匹配
istartswith 不区分大小写从开头匹配
endswith 不区分大小写从结尾处匹配
range 范围匹配
date 日期匹配
year 年份
iso_year 以ISO 8601标准确定的年份
month 月份
day 日期
week 第几周
week_day 周几
iso_week_day 以ISO 8601标准确定的星期几
quarter 季度
time 时间
hour 小时
minute 分钟
second
regex 区分大小写的正则匹配
iregex 不区分大小写的正则匹配

以上字段条件查询对非JSONField 类型的模型字段,同样适用

class TestJsonField(TestCase):

    def setUp(self) -> None:
        print('====================新增数据======================')
        req1 = Request.objects.create(method=1,url='/mgr/student/',data={"name":"小明","age":16,"address":"广东广州","school":{"PrimarySchool":"实验小学","SecondarySchool":"第一中学"}})
        req2 = Request.objects.create(method=0,url='/api/teacher/',data={"name":"小王老师","courses":"英语","address":"广东深圳"})
        req3 = Request.objects.create(method=3,url='/api/delete/',data={"id":105,"display_idx":1})


    def test_json_02(self):
        print('====================字段条件查询======================')
        req4 = Request.objects.filter(url__contains='mgr')
        print(req4)
        req5 = Request.objects.filter(method__in=[0,1,2])
        print(req5)

输出结果

====================字段条件查询======================
<QuerySet [<Request: /mgr/student/>]>
<QuerySet [<Request: /mgr/student/>, <Request: /api/teacher/>]>
跨关系查询

Django提供了强大并且直观的方式解决跨越关联的查询,它在后台自动执行包含 JOIN 的 SQL语句。要跨越某个关联,只需使用关联的模型字段名称,并使用双下划线分隔,直至你想要的字段(可以链式跨越,无限跨度)

class TestOverRelations(TestCase):
    def setUp(self) -> None:
        # 创建用例
        self.config1 = Config.objects.create(name='用例1', base_url='http://127.0.0.1:8080/')
        self.config2 = Config.objects.create(name='用例2', base_url='http://127.0.0.1:8888/')
        self.case1 = Case.objects.create(config=self.config1)
        self.case2 = Case.objects.create(config=self.config2)

    def test_step_request(self):
        # 准备测试数据 步骤和请求
        step1 = Step.objects.create(belong_case=self.case1,name='步骤1')
        step2 = Step.objects.create(belong_case=self.case1,name='步骤2')
        step3 = Step.objects.create(belong_case=self.case2,name='步骤3')
        req1 = Request.objects.create(method=0,url='/api/teacher1/',data={"name":"小王老师","courses":"英语","address":"广东深圳"},step=step1)
        req2 = Request.objects.create(method=1,url='/api/teacher2/',data={"name":"小王老师","courses":"英语","address":"广东深圳"},step=step2)
        req3 = Request.objects.create(method=2,url='/api/teacher3/',data={"name":"小王老师","courses":"英语","address":"广东深圳"},step=step3)

        print(req1.step.belong_case) # 链式语法 通过请求查询步骤再查询所属的用例(通过模型关联一步步查询    
        print(Request.objects.filter(step=step1))   
        # 跨关系查询
        print(Request.objects.filter(step__belong_case__config__name='用例1'))   # 查询 用例1 下的步骤

跨关系查询语法:字段__关联字段

跨关系查询是根据上级数据特征查找下级的结果

用例1
<QuerySet [<Request: /api/teacher1/>]>
<QuerySet [<Request: /api/teacher1/>, <Request: /api/teacher2/>]>
修改
from django.test import TestCase

# Create your tests here.

from sqtp.models import Case, Config, Step, Request
from django.db.models import Value

class TestJsonField(TestCase):

    def setUp(self) -> None:
        print('====================新增数据======================')
        req = Request.objects.create(method=1,url='/mgr/student/',data={"name":"小明","age":16,"address":"广东广州","school":{"PrimarySchool":"实验小学","SecondarySchool":"第一中学"}})
        
    def test_json_04(self):

        print('====================查询数据======================')
        req1 = Request.objects.all().first()
        print(req1)
        print(req1.data) # 查询data数据内容

        print('====================修改整个字段内容======================')
        req1.data={"name":"小王","age":16,"籍贯":"江西南昌"}
        req1.save()
        print(Request.objects.all().first().data) # 查看修改后的内容

        print('====================修改字段中json局部内容======================')
        req2 = Request.objects.all().first()
        print(req2.data['name']) # 修改前
        req2.data['name'] = '小红'
        req2.save()
        print(Request.objects.all().first().data['name']) # 修改后    
    

输出结果

====================查询数据======================
/mgr/student/
{'name': '小明', 'age': 16, 'address': '广东广州', 'school': {'PrimarySchool': '实验小学', 'SecondarySchool': '第一中学'}}
====================修改整个字段内容======================
{'name': '小王', 'age': 16, '籍贯': '江西南昌'}
====================修改字段中json局部内容======================
小王
小红

修改data字段的内容,data字段就变为了{'name': '小王', 'age': 16, '籍贯': '江西南昌'};如果只需要修改json数据中的部分内容,只需要对字典中下标名称进行赋值即可,保存后json数据的内容就修改成功了

删除
from django.test import TestCase

# Create your tests here.

from sqtp.models import Case, Config, Step, Request
from django.db.models import Value

class TestJsonField(TestCase):

    def setUp(self) -> None:
        print('====================新增数据======================')
        req = Request.objects.create(method=1,url='/mgr/student/',data={"name":"小明","age":16,"address":"广东广州","school":{"PrimarySchool":"实验小学","SecondarySchool":"第一中学"}})
        
    def test_json_05(self):
        print('====================查询数据======================')
        req1 = Request.objects.all().first()
        print(req1)
        print(req1.data) # 查询data数据内容

        print('====================删除字段局部的内容======================')
        req1.data.pop('name')
        req1.save()
        print(Request.objects.all().first().data)

        print('====================删除整个字段的内容======================')
        req1.data = Value('null') # 设置成json的null
        # req1.data = None # 设置成sql的null
        req1.save()
        print(Request.objects.all().first().data)

输出结果

====================查询数据======================
/mgr/student/
{'name': '小明', 'age': 16, 'address': '广东广州', 'school': {'PrimarySchool': '实验小学', 'SecondarySchool': '第一中学'}}
====================删除字段局部的内容======================
{'age': 16, 'address': '广东广州', 'school': {'PrimarySchool': '实验小学', 'SecondarySchool': '第一中学'}}
====================删除整个字段的内容======================
None

删除字段json数据中的内容,则是通过pop()函数完成;删除整个字段的数据,则是字段内容置为null文章来源地址https://www.toymoban.com/news/detail-433075.html

到了这里,关于Django JSONField类型操作解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Django JSONField的自动转换(django自定义模型字段)

    Django v3.1的主要更新之一便是完善了对JSON数据存储的支持,新增models.JSONField和forms.JSONField,可在所有受支持的数据库后端上使用。 通过models.JSONField可指定此字段为存储类型为JSON格式。null=True表示此字段可以为空。 如果您想实现JSONField的自动转换,可以使用Django REST framework的

    2024年02月08日
    浏览(54)
  • 【测试开发】Python+Django实现接口测试工具

    Python+Django接口自动化  引言:          最近被几个公司实习生整自闭了,没有基础,想学自动化又不知道怎么去学,没有方向没有头绪,说白了其实就是学习过程中没有成就感,所以学不下去。出于各种花里胡哨的原因,今天给大家整一个简单又有成就感的接口自动化学习

    2024年02月15日
    浏览(52)
  • python django vue httprunner 实现接口自动化平台(最终版)

    后端地址: GitHub - 18713341733/test_platform_service: django vue 实现接口自动化平台 前端地址: GitHub - 18713341733/test_platform_front: Django vue实现接口自动化平台 1.2.1 环境准备 Python = 3.8.0 (推荐3.9+版本) nodejs = 14.0 (推荐最新) 或者 16,千万不要使用18(会报错) Mysql = 5.7.0 (可选,默认数据库

    2024年02月10日
    浏览(38)
  • Django实现接口自动化平台(十三)接口模块Interfaces序列化器及视图【持续更新中】

    相关文章: Django实现接口自动化平台(十二)自定义函数模块DebugTalks 序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客 本章是项目的一个分解,查看本章内容时,要结合整体项目代码来看: python django vue httprunner 实现接口自动化平台(最终版)_python+vue自动化测

    2024年02月17日
    浏览(44)
  • Django实现接口自动化平台(十)自定义action names【持续更新中】

    相关文章: Django实现接口自动化平台(九)环境envs序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客 深入理解DRF中的Mixin类_做测试的喵酱的博客-CSDN博客  python中Mixin类的使用_做测试的喵酱的博客-CSDN博客  本章是项目的一个分解,查看本章内容时,要结合整体项

    2024年02月16日
    浏览(69)
  • 搭建Django+pyhon+vue自动化测试平台

    Django安装 使用管理员身份运行pycharm使用local    检查django是否安装成功     创建项目 cd 切换至创建的项目中启动django项目 启动项目 点击连接跳转至浏览器  更改django为中文settings文件---LANGUAGE_CODE Vue安装 安装cnpm,代替npm指令,速度快        安装vue脚手架         切换至

    2024年02月14日
    浏览(43)
  • 【Django学习】(十五)API接口文档平台_项目流程分析_日志器_认证_授权

    使用API接口文档不经可以很好的的维护接口数据,还给测试人员的接口测试工作带来了便利; 我们可以在全局配置文件中添加路由路径生成接口文档 1.1在全局配置文件里指定用于支持coreapi的Schema 1.2在全局路由表中添加路径   页面效果: 2.1 一定要先在配置表中注册drf_yas

    2024年02月15日
    浏览(61)
  • Django实现接口自动化平台(九)环境envs序列化器及视图【持续更新中】

    相关文章: Django实现接口自动化平台(八)测试报告reports序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客 本章是项目的一个分解,查看本章内容时,要结合整体项目代码来看: python django vue httprunner 实现接口自动化平台(最终版)_python+vue自动化测试平台_做测

    2024年02月16日
    浏览(46)
  • docker+django+ubuntu服务器 测试质量管理平台部署

      然后setting.py中增加服务器ip地址 0.0.0.0开放所有 其中setting.py注意 DEBUG = False 是False的话js和css的静态文件不会生效 在此注意一下!!!!!!! 2.拉取git的项目代码 构建成镜像 镜像run成容器 其中8888是容器内部的端口号,8886是对外开放的端口号  没有报错说明就是成功了 最后直接访

    2024年02月01日
    浏览(54)
  • 一文搞定接口测试及常用接口测试工具解析

    目录 首先,什么是接口呢? 一、常见接口: 二、前端和后端: 三、什么是接口测试: 四、接口组成 五、为什么要做接口测试: 六、接口测试怎么测:  七、用什么工具测 接口一般来说有两种,一种是程序内部的接口,一种是系统对外的接口。 系统对外的接口:比如你要

    2024年02月03日
    浏览(89)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包