本章节演示如何创建接口服务,用接口关联数据库数据,包括get请求和post请求。

一、Flask-RESTful插件

restful api是用于在前端与后台进行通信的一套规范。使用这个规范可以让前后端开发变得更加轻松。以下将讨论这套规范的一些设计细节。

英文地址:https://flask-restful.readthedocs.io/en/latest/

中文地址:http://www.pythondoc.com/Flask-RESTful/index.html

安装命令:

pip install flask-restful

上代码,红色字体为使用插架用法:

from flask import Flask
from flask_restful import Resource, Api
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
# 配置数据库详细信息
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:1234567@localhost:8881/2022.8.3Data'
# 初始化一个db
db = SQLAlchemy(app)
# 将flask实例加载到flask-restful
api = Api(app) class TestCase(db.Model):
id = db.Column(db.Integer, primary_key=True)
nodeid = db.Column(db.String(80), unique=True, nullable=False)
description = db.Column(db.String(120), unique=False, nullable=True) def __repr__(self):
return f'<User {self.username} {self.email}>' # 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
return {'hello': 'get'} def post(self):
return {'hello': 'post'} # 添加到flask-restful中,并增加路由
api.add_resource(TestCaseServer, '/') if __name__ == '__main__':
# db.drop_all()
# db.create_all()
#
#
# for i in range(30):
# data = TestCase(nodeid=f'nodeid_{i+1}', description=f'备注{i+1}')
# db.session.add(data)
# db.session.commit() app.run(debug=True)

1、GET请求

在浏览器中输入地址:http://127.0.0.1:5000/

2、POST请求

>>> import requests
>>> r = requests.post("http://127.0.0.1:5000")
>>> r.text '{\n "hello": "post"\n}\n'

二、接口查询数据(GET)

使用GET接口查询数据

from flask import Flask
from flask_restful import Resource, Api
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
# 配置数据库详细信息
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:1234567@localhost:8881/2022.8.3Data'
# 初始化一个db
db = SQLAlchemy(app)
# 将flask实例加载到flask-restful
api = Api(app) class TestCase(db.Model):
id = db.Column(db.Integer, primary_key=True)
nodeid = db.Column(db.String(80), unique=True, nullable=False)
description = db.Column(db.String(120), unique=False, nullable=True) def as_dict(self):
"""
返回测试用例的数据
:return:
"""
return {"id": self.id, "nodeid": self.nodeid, "description": self.description} # 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
"""
获取所有测试用例数据
:return:
"""
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases def post(self):
return {'hello': 'post'} # 添加到flask-restful中,并增加路由
api.add_resource(TestCaseServer, '/testcase') if __name__ == '__main__': app.run(debug=True)

三、接口新增数据(POST)

1、首先验证使用post接口接收数据

# 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
"""
获取所有测试用例数据
:return:
"""
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases def post(self):
"""
新增用例
:return:
"""
nodeid = request.json.get("nodeid")
description = request.json.get("description")
return [nodeid, description] # 添加到flask-restful中,并增加路由
api.add_resource(TestCaseServer, '/testcase')

Python Console输入post请求:

>>> import requests
>>> r = requests.post("http://127.0.0.1:5000/testcase", json={"nodeid": '999', "description": '999感冒灵'})
>>> r.text '[\n "999",\n "999\\u611f\\u5192\\u7075"\n]\n'

这个例子介绍post接口如何接收数据。

2、post接口结合数据库进行关联(※重点)

from flask import Flask, request
from flask_restful import Resource, Api
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
# 配置数据库详细信息
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:1234567@localhost:8881/2022.8.3Data'
# 初始化一个db
db = SQLAlchemy(app)
# 将flask实例加载到flask-restful
api = Api(app) class TestCase(db.Model):
id = db.Column(db.Integer, primary_key=True)
nodeid = db.Column(db.String(80), unique=True, nullable=False)
description = db.Column(db.String(120), unique=False, nullable=True) def as_dict(self):
"""
返回测试用例的数据
:return:
"""
return {"id": self.id, "nodeid": self.nodeid, "description": self.description} # 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
"""
获取所有测试用例数据
:return:
"""
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases def post(self):
"""
新增用例
:return:
"""
# 把消息体中的数据,发送到数据库中
data = TestCase(**request.json)
db.session.add(data)
db.session.commit()
return {'msg': 'OK'} # 添加到flask-restful中,并增加路由
api.add_resource(TestCaseServer, '/testcase') if __name__ == '__main__': app.run(debug=True)

Python Console输入post请求:

>>> r = requests.post("http://127.0.0.1:5000/testcase", json={"nodeid": '999', "description": '999感冒灵'})
>>> r.text # 结果
'{\n "msg": "OK"\n}\n'

数据库新增数据:

四、接口删除数据(GET)

1、首先验证使用post接口接收数据

# 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
"""
(一)获取所有测试用例数据
(二)删除测试用例数据
:return:
"""
option = request.args.get("option")
if option == 'get_testcase':
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases
# 如果url中option参数值为del_testcase,代表删除用例
elif option == 'del_testcase':
nodeid = request.args.get("nodeid")
return nodeid

浏览器输入:http://127.0.0.1:5000/testcase?option=del_testcase&nodeid=1234

2、可以通过get接口接收数据,下一步关联数据库(※重点)

from flask import Flask, request
from flask_restful import Resource, Api
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
# 配置数据库详细信息
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:1234567@localhost:8881/2022.8.3Data'
# 初始化一个db
db = SQLAlchemy(app)
# 将flask实例加载到flask-restful
api = Api(app) class TestCase(db.Model):
id = db.Column(db.Integer, primary_key=True)
nodeid = db.Column(db.String(80), unique=True, nullable=False)
description = db.Column(db.String(120), unique=False, nullable=True) def as_dict(self):
"""
返回测试用例的数据
:return:
"""
return {"id": self.id, "nodeid": self.nodeid, "description": self.description} # 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
"""
(一)获取所有测试用例数据
(二)删除测试用例数据
:return:
"""
option = request.args.get("option")
if option == 'get_testcase':
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases
# 如果url中option参数值为del_testcase,代表删除用例
elif option == 'del_testcase':
nodeid = request.args.get("nodeid")
# 查询用例后进行删除
data = TestCase.query.filter_by(nodeid=nodeid).first()
try:
db.session.delete(data)
db.session.commit()
return {'msg': 'delete is ok!'}
except:
return {'msg': 'delete is error!'} def post(self):
"""
新增用例
:return:
"""
data = TestCase(**request.json)
db.session.add(data)
db.session.commit()
return {'msg': 'OK'} # 添加到flask-restful中,并增加路由
api.add_resource(TestCaseServer, '/testcase') if __name__ == '__main__': app.run(debug=True)

浏览器输入地址:http://127.0.0.1:5000/testcase?option=del_testcase&nodeid=999

数据库删除了这条数据!

3、接口批量删除数据

# 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
"""
(一)获取所有测试用例数据
(二)删除测试用例数据
:return:
"""
option = request.args.get("option")
if option == 'get_testcase':
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases
# 如果url中option参数值为del_testcase,代表删除用例
elif option == 'del_testcase':
nodeid = request.args.get("nodeid")
# 查询用例后进行删除
data = TestCase.query.filter_by(nodeid=nodeid).first()
try:
db.session.delete(data)
db.session.commit()
return {'msg': 'delete is ok!'}
except:
return {'msg': 'delete is error!'}
elif option == 'del_testcases':
nodeids = request.args.get("nodeids")
for nodeid in nodeids.split(','):
# 查询用例后进行批量删除
data = TestCase.query.filter_by(nodeid=nodeid).first()
try:
db.session.delete(data)
except:
return {'msg': 'delete is error!'}
db.session.commit()
return {'msg': 'delete is ok!'} api.add_resource(TestCaseServer, '/testcase')

if __name__ == '__main__':

    app.run(debug=True)

浏览器输入:http://127.0.0.1:5000/testcase?option=del_testcases&nodeids=888,999

删除前:

删除后:

五、接口更新数据——API接口Url分开

为什么要分开写呢,因为如果项目足够大,不能只用一个Url写各种各样的接口,需要我们把Url区分一下,一个接口一个Url。

1、写法一

# 定义测试用例更新接口
class TestCaseUpdate(Resource):
"""更新测试用例"""
def post(self):
nodeid = request.args.get('nodeid')
data = TestCase.query.filter_by(nodeid=nodeid).first()
data.description = '藿香正气水'
db.session.commit()
return {'msg': 'update is success!'} # 添加到flask-restful中,并增加更新路由
api.add_resource(TestCaseUpdate, '/testcase/update')

Python Console输入:

>>> r = requests.post("http://127.0.0.1:5000/testcase/update?nodeid=999")
>>> r.text # 结果
'{\n "msg": "update is success!"\n}\n'

2、写法二(推荐※)

# 定义测试用例更新接口
class TestCaseUpdate(Resource):
"""更新测试用例"""
def post(self):
request_body = request.json
data = TestCase.query.filter_by(nodeid=request_body.get('nodeid')).first()
data.description = request_body.get('description')
db.session.commit()
return {'msg': 'update is success!'} # 添加到flask-restful中,并增加更新路由
api.add_resource(TestCaseUpdate, '/testcase/update')

Python Console输入:

>>> r = requests.post("http://127.0.0.1:5000/testcase/update", json={'nodeid': 999, "description": '999感冒灵'})
>>> r.text # 结果
'{\n "msg": "update is success!"\n}\n'

六、整合所有API接口(重点※※※※※)

对于以上接口,全部采取Url分开的写法进行整合:

from flask import Flask, request
from flask_restful import Resource, Api
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
# 配置数据库详细信息
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:1234567@localhost:8881/2022.8.3Data'
# 初始化一个db
db = SQLAlchemy(app)
# 将flask实例加载到flask-restful
api = Api(app) class TestCase(db.Model):
id = db.Column(db.Integer, primary_key=True)
nodeid = db.Column(db.String(80), unique=True, nullable=False)
description = db.Column(db.String(120), unique=False, nullable=True) def as_dict(self):
"""
返回测试用例的数据
:return:
"""
return {"id": self.id, "nodeid": self.nodeid, "description": self.description} # 定义测试用例新增接口
class TestCaseAdd(Resource):
def post(self):
"""
新增用例
:return:
"""
data = TestCase(**request.json)
db.session.add(data)
db.session.commit()
return {'msg': 'Add is OK!'} # 定义测试用例删除接口
class TestCaseDelete(Resource):
# get方法代表接收get请求
def get(self):
"""
删除测试用例数据
:return:
"""
if "nodeid" in request.args:
nodeid = request.args.get("nodeid")
# 查询用例后进行删除
data = TestCase.query.filter_by(nodeid=nodeid).first()
try:
db.session.delete(data)
db.session.commit()
return {'msg': 'delete is ok!'}
except:
return {'msg': 'delete is error!'}
elif "nodeids" in request.args:
nodeids = request.args.get("nodeids")
print(nodeids)
# 查询用例后进行批量删除
for nodeid in nodeids.split(','):
data = TestCase.query.filter_by(nodeid=nodeid).first()
try:
db.session.delete(data)
except:
return {'msg': 'delete is error!'}
db.session.commit()
return {'msg': 'delete is ok!'} # 定义测试用例更新接口
class TestCaseUpdate(Resource):
"""更新测试用例"""
def post(self):
request_body = request.json
data = TestCase.query.filter_by(nodeid=request_body.get('nodeid')).first()
data.description = request_body.get('description')
db.session.commit()
return {'msg': 'update is success!'} # 定义测试用例查询接口
class TestCaseSearch(Resource):
# get方法代表接收get请求
def get(self):
"""
(一)获取所有测试用例数据
:return:
"""
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases # 添加到flask-restful中,并增加新增路由
api.add_resource(TestCaseAdd, '/testcase/add')
# 添加到flask-restful中,并增加删除路由
api.add_resource(TestCaseDelete, '/testcase/delete')
# 添加到flask-restful中,并增加更新路由
api.add_resource(TestCaseUpdate, '/testcase/update')
# 添加到flask-restful中,并增加查询路由
api.add_resource(TestCaseSearch, '/testcase/search') if __name__ == '__main__':
# db.drop_all()
# db.create_all()
#
#
# for i in range(30):
# data = TestCase(nodeid=f'nodeid_{i+1}', description=f'备注{i+1}')
# db.session.add(data)
# db.session.commit() app.run(debug=True)

七、说明一下接口类型

参考文章:感谢故屿γ的《Get、Put、Post、Delete 含义与区别

1、GET 请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的 select 操作一样,只是用来查询一下数据,不会修改、增加数据,不会影响资源的内容,即该请求不会产生副作用。无论进行多少次操作,结果都是一样的。

2、PUT 请求是向服务器端发送数据的(与 GET 不同)从而改变信息,该请求就像数据库的 update 操作一样,用来修改数据的内容,但是不会增加数据的种类等,也就是说无论进行多少次 PUT 操作,其结果并没有不同。

3、POST 请求同 PUT 请求类似,都是向服务器端发送数据的,但是该请求会改变数据的种类等资源,就像数据库的 insert 操作一样,会创建新的内容。几乎目前所有的提交操作都是用 POST 请求的。

4、DELETE 请求顾名思义,就是用来删除某一个资源的,该请求就像数据库的 delete 操作。

就像前面所讲的一样,既然 PUT 和 POST 操作都是向服务器端发送数据的,那么两者有什么区别呢? POST 主要作用在一个集合资源之上的(url),而 PUT 主要作用在一个具体资源之上的(url/xxx),通俗一下讲就是,如 URL 可以在客户端确定,那么可使用 PUT,否则用 POST。

总结一下,Get 是向服务器发索取数据的一种请求,而 Post 是向服务器提交数据的一种请求,在 FORM(表单)中,Method默认为 “GET”,实质上,GET 和 POST 只是发送机制不同,并不是一个取一个发。

基于上面的代码,总结一下接口类型使用:

POST  /url/add       新增

POST  /url/update    更新

GET   /url/delete    删除

GET   /url/search    查询

八、自动化平台系列文章汇总

【测试平台开发】——开篇章节

【测试平台开发】——06Flask后端api开发实战(三)——API接口关联数据库的更多相关文章

  1. teprunner测试平台用例前置模块开发

    本文开发内容 现在正式进入测试相关功能开发.teprunner测试平台底层是pytest,中间层是tep,还没了解的朋友可以先看看tep的文章,整个平台的设计思路和后面用例的执行都会基于这个工具.te ...

  2. django 开发之前后端分离开发模式

    1. 什么是前后端分离开发的概念: 前端页面运行前端服务器上,负责页面的渲染(静态文件的加载)与跳转 后端代码运行在后端服务器上, 负责数据的处理(提供数据请求的接口) 2. 前后端分离开发碰到的问题 ...

  3. java开发-前后端分离

    众所周知,做java开发是后端的开发,我们时常与前端打交道,但更加注重后端代码的实现,前台的页面都是由前端开发人员做的,那么,是怎么做到前后端分离的呢? 首先,是后端的开发, 在mapper层:Stu ...

  4. java EE技术体系——CLF平台API开发注意事项(1)——后端开发

    前言:这是一篇帮助小伙伴在本次项目中快速进入到java EE开发的一些说明,为了让同组小伙伴们开发的时候,有个清晰点的思路.昨天给大家演示分享了基本概况,但没有留下文字总结说明,预防后期有人再次问我, ...

  5. 前后端分离开发,基于SpringMVC符合Restful API风格Maven项目实战(附完整Demo)!

    摘要: 本人在前辈<从MVC到前后端分离(REST-个人也认为是目前比较流行和比较好的方式)>一文的基础上,实现了一个基于Spring的符合REST风格的完整Demo,具有MVC分层结构并 ...

  6. java EE技术体系——CLF平台API开发注意事项(4)——API生命周期治理简单说明

    文档说明 截止日期:20170905,作者:何红霞,联系方式:QQ1028335395.邮箱:hehongxia626@163.com 综述 有幸加入到javaEE技术体系的研究与开发,也得益于大家的 ...

  7. [转] 前后端分离开发模式的 mock 平台预研

    引入 mock(模拟): 是在项目测试中,对项目外部或不容易获取的对象/接口,用一个虚拟的对象/接口来模拟,以便测试. 背景 前后端分离 前后端仅仅通过异步接口(AJAX/JSONP)来编程 前后端都 ...

  8. 学习版pytest内核测试平台开发万字长文入门篇

    前言 2021年,测试平台如雨后春笋般冒了出来,我就是其中一员,写了一款pytest内核测试平台,在公司落地.分享出来后,有同学觉得挺不错,希望能开源,本着"公司代码不要传到网上去,以免引起 ...

  9. 测试开发【提测平台】分享3-正式开发产品需求&项目初始化

    上两个分享主要是介绍和演示基本前后端所要使用的框架,接下来我们将正式进入到[提测平台的开发] 提要先给出依赖和内容点: 提测平台定义和产品原型需求说明 使用github创建代码仓库进行项目管理 Fla ...

  10. 超越村后端开发(4:API开发)

    1.users相关的api开发 1.在settings中添加APPID,SECRET 2.在apps/users/views.py内: from chaoyuecun.settings import ...

随机推荐

  1. 随机森林R语言预测工具

    随机森林(Random Forest)是一种基于决策树的集成学习方法,它通过构建多个决策树并集成它们的预测结果来提高预测的准确性.在R语言中,我们可以使用randomForest包来构建和训练随机森林 ...

  2. [UG 二次开发 python] 生成略缩图并保存

    保存到零件同名的文件夹下,名称相同,类型是 jpg 用到 numpy,PIL,cv2 blockstyler 文件略 # nx: threaded __version__ = "0.0.1& ...

  3. 在Docker中搭建rabbit MQ集群 (Mac + OrbStack)

    我以为用docker搭建一个rabbitMq集群会非常简单,但是结果却出乎意料,我花了差不多两个半天才搞定.这还是依赖了AI的协助,否则难度不敢想象. 我的环境是Mac上的OrbStack.用了Kim ...

  4. windows下rust环境的安装(现在是2023年5月份)

    在自己家电脑上安装一下rust,还是遇到一些问题,这里记录一下,免得后面再踩坑. 官方网站 获取主要信息还得靠官网,比如安装软件:) 地址是 https://www.rust-lang.org/zh- ...

  5. P8451 题解

    显然,题面明摆着让你写一个可持久化 AC 自动机. 但是从空间来说这是不可能的. 想起做 不强制在线 的可持久化数据结构的一种方法,建立"时光树",具体来说,假若版本 \(x\) ...

  6. python3 模型日记

    说明 作为一种 python 框架模型的记录吧,用于个人总结,不定时更新. 正文 1. 主进程退出后,子进程也跟着退出 之前遇到过一种情况,用 flet 写了一个页面,然后又同时开了一个 tcp se ...

  7. ubuntu20使用php+apache+adminer搭建mysql网页管理工具

    前言   使用 php7+apache2+adminer 搭建网页版mysql管理工具,现将自己的搭建过程记录下来,留作后续参考.可参考其中配置,由于只配置了一次环境,可能有的步骤是多余的,后续可能会 ...

  8. TCP/UDP 协议和 HTTP/FTP/SMTP 协议之间的区别

    前言 我们经常会听到HTTP协议.TCP/IP协议.UDP协议.Socket.Socket长连接.Socket连接池等字眼,然而它们之间的关系.区别及原理并不是所有人都能理解清楚. 计算机网络体系结构 ...

  9. SpringBoot注解配置文件映射属性和实体类

    配置文件加载 方式一 Controller上面配置@PropertySource({"classpath:pay.properties"}) 添加属性@Value("wx ...

  10. oeasy教您玩转vim - 45 - # 按行编辑

    ​ 按行编辑 回忆上节课内容 上次我们主要就是综合运用 很好玩的,更快速的解决问题 进行计算 ctrl+a,将具体的数字加1 ctrl+x,将具体的数字减1 5ctrl+a,将具体的数字加5 一次命令 ...