本章节演示如何创建接口服务,用接口关联数据库数据,包括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. v-model 的原理?

    我们在 vue 项目中主要使用 v-model 指令在表单 input.textarea.select 等元素上创建双向数据绑定,我们知道 v-model 本质上不过是语法糖,v-model 在内部为 ...

  2. Spring AOP里面的通知Advice类型

    @Before前置通知 在执行目标方法之前运行 @After后置通知 在目标方法运行结束之后 @AfterReturning返回通知 在目标方法正常返回值后运行 @AfterThrowing异常通知 ...

  3. 洛谷P1464

    搜索优化后是记忆化搜索,再优化就是dp了 #include <iostream> #include <utility> using namespace std; typedef ...

  4. JDBC第二天:防sql攻击

    1 什么是SQL攻击 在需要用户输入的地方,用户输入的是SQL语句的片段,最终用户输入的SQL片段与我们DAO中写的SQL语句合成一个完整的SQL语句!例如用户在登录时输入的用户名和密码都是为SQL语 ...

  5. Asp .Net Core 系列:详解授权以及实现角色、策略、自定义三种授权和自定义响应

    什么是授权(Authorization)? 在 ASP.NET Core 中,授权(Authorization)是控制对应用资源的访问的过程.它决定了哪些用户或用户组可以访问特定的资源或执行特定的操作 ...

  6. adb shell 批处理文件

    adb shell 批处理文件 手机截屏,并把图片传到电脑

  7. exceptionx:灵活便捷的Python异常处理库,让异常处理更高效!

    exceptionx English | 中文 exceptionx 是一个灵活且便捷的Python异常处理库,允许你动态创建异常类,并提供多种异常处理机制. exceptionx 的前身是 gqyl ...

  8. 【Java】三元运算符 类型提升 问题

    代码片段: @Test public void test() { Object o = true ? new Integer(1) : new Double(2); System.out.printl ...

  9. 中国特供版4090D已经开始发售

    由于美国政府的限制,NVIDIA公司等美国公司不允许向中国出口4090显卡,但是为了绕过美国政府的限制NVIDIA公司推出了中国特供版的4090D显卡. 4090d显卡和4090显卡区别大吗?可以说其 ...

  10. docker 容器(container)使用ssh服务登录一段时间无操作后自动断开问题解决

    如题,ssh登录建立好的docker容器,无操作一段时间后,发现ssh自动断开: 解决方法: 修改配置文件 /ect/ssh/sshd_config 在文件最后添加下面内容: PermitRootLo ...