restful
属于一种快速构建api的一种工具,和django的还是不相同的
安装
pip install flask-restful
可以和django一样进行 定义 类视图的方式
但是falskrestful中可以直接返回字典格式,它自动转换为json格式给客户端
基本的使用
from flask import Flask
from flask_restful import Resource, Api # 导入restful中的 Resource 和api
app = Flask(__name__)
api = Api(app) # 创建一个restful的api对象,将flaks的实例对象app传入
# 没有了django的序列化器的概念
# 设置路视图 继承flask_restful 中的 Resource
class HellWord(Resource):
def get(self):
return {'name': 'hello'} # 不需要在进行转换json格式,内部已经 帮助转换过了
def post(self):
return {'age': '18'}
# 使用api对象,将类视图,和路由信息进行绑定
# add_resource 帮我们调用了django的 as
api.add_resource(HellWord, '/') # hellword 类视图, / 为绑定的路径
if __name__ == '__main__':
app.run()
127.0.0.1/ get {'name': 'hello'}
127.0.0.1/psot {'age': '18'}
# 补充 在对象api.add_resource将 类视图和路由绑定的时候,可以进行设置一个路由的别名
api.add_resource(HellWord, '/',endpoint='HelloWorld')
通过这个参数endpoint
蓝图使用restful
from flask import Flask, Blueprint
from flask_restful import Resource, Api
app = Flask(__name__)
bp = Blueprint('bp', __name__) # 1.创建蓝图对象
bp_api = Api(bp) # 2.将蓝图对象传入,创建一个蓝图的api对象(绑定蓝图对象api对象)
class HellWord(Resource):
def get(self):
return {'name': 'hello'}
bp_api.add_resource(HellWord, '/bp/helloword') # 3.由蓝图对象调用add_resource 绑定视图类与路径
# 蓝图注册,你不注册到flask全局对象中,蓝图的url是不会显示的
app.register_blueprint(bp) # 4.还是需要将蓝图注册到全局的app flask对象中的
if __name__ == '__main__':
app.run()
restful视图使用装饰器
使用Resource 继承的 类视图的父类,中的method_decorators 属性进行使用
1.列表方式装饰器
# 这个属性是由flask_restful框架中的 resource的属性当每次访问时,就会读取当前的 method_decorators
# 1.当成一个列表 如果装饰器不做区分的话,使用列表,那么全部的请求方式都会加上装饰器
# 2.当成一个字典 如果类视图中想要不同的条件加上不同的装饰器,那么就是用字典的形式
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
def decorator1(func):
def wrapper(*args, **kwargs):
print('装饰器1')
return func(*args, **kwargs)
return wrapper
def decorator2(func): # 先打印
def wrapper(*args, **kwargs):
print('装饰器2')
return func(*args, **kwargs)
return wrapper
class UserInfo(Resource):
method_decorators = [decorator1, decorator2] # 装饰器2 先被打印
'''
内部原理
for i in method_decorators:
func = i(get) # 将当前的get请求的方法传入
第一次遍历:
get1 = func1(get) # 装饰器
第二次遍历
get2 = func2(get1) # 将上面的装饰器对象get1传入装饰器方法2中
相当于:
@decorator2 最外层的装饰器 将下面的内容当成参数
@decorator1
def func()
理解:
decorator2(decorator1(get)) # 将下面的东西全部传入
'''
def get(self):
return {'name': 'wkx'}
def post(self):
return {'pwd': 123}
api = Api(app)
api.add_resource(UserInfo, '/')
if __name__ == '__main__':
app.run(debug=True)
# 为什么先打印第二个不是第一个:
decorator2(decorator1(get))
--> decorator2( decorator1(get) --> wrapper内部的函数名字 内部的func指的就是get函数)
-->decorator2 --> 返回wrapper 内部的函数名字 其中里面的func指定就是
### decorator1(get) --> wrapper内部的函数
当 get方法被调用的使用
执行 decorator2 --> 返回wrapper 方法 中的 func(是decorator1 中的wrapper)
执行后 就会还行decorator1中的wrapper 内部的func(就是get方法)
调用装饰器 :外部的方法执行
调用被装饰的函数 :才是装饰器内部的方法被执行
####字典形式装饰 根据不同的请求装饰 不同数量的装饰器
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
def decorator1(func):
def wrapper(*args, **kwargs):
print('装饰器1')
return func(*args, **kwargs)
return wrapper
def decorator2(func):
def wrapper(*args, **kwargs):
print('装饰器2')
return func(*args, **kwargs)
return wrapper
class UserInfo(Resource):
method_decorators = {
'get': [decorator1, decorator2], # 给get 装饰两个
'post': [decorator2] # 给 post 装饰一个
}
def get(self):
return {'name': 'wkx'}
def post(self):
return {'pwd': 123}
api = Api(app)
api.add_resource(UserInfo, '/')
if __name__ == '__main__':
app.run(debug=True)
获取请求参数
原生的是request对象获取请求。
restful 提供了requestParset类 用来帮我们校验和转换请求数据的
# 简单的操作
from flask_restful.reqparse import RequestParser # 对request的进一步的封装
from flask import Flask
from flask_restful import Resource, Api
from flask_restful.reqparse import RequestParser
app = Flask(__name__)
class UserInfo(Resource):
# http://127.0.0.1:5000/?a=10&b=20
def get(self):
# 作用帮我们省去了前端数据传入时的判断
# 1. 创建对象
rp = RequestParser()
# 2.声明前端传入参数
rp.add_argument('a') # 参数名(存在几个就调用几个方法)
rp.add_argument('b')
# 3.执行对参数执行校验
res = rp.parse_args() # 可以将这个返回校验内容可以当对象和字典
print(res) # {'a': '10', 'b': '20'}
# res.a 或者res.['a']
return {'name': 'wkx'}
api = Api(app)
api.add_resource(UserInfo, '/')
if __name__ == '__main__':
app.run(debug=True)
参数说明
1.required # 参数到底需不需要传递
参数默认为 False 可以不用传值
rp.add_argument('a', required=True) 报错400
# 如果设置为true,不传值的情况下,就会提示错误提示,参数必须要传
2. help 参数,定制错误的提示
rp.add_argument('a', required=True,help='参数必须传入')
# 如果这个参数不传入 的情况下,就会提示help定制的内容
3.action 如果传入的参数同名的情况下
默认 action='store' 保留出现的第一个
action = 'append' 一列表的形式追加保存同名参数的值
rp.add_argument('a', required=True,help='参数必须传入',action='append')
http://127.0.0.1:5000/?a=10&a=40&a=50
{a:[10,40,50]}
4.type 类型的制定
1.自带
str 会将全部的参数全部转换为字符串
rp.add_argument('a', required=True,help='参数必须传入',type=str)
int 传入其他类型报错,如果可以转换,那么他会转换为int
rp.add_argument('a', required=True,help='参数必须传入',type=int)
在inputs模块中指定的其他类型
from flask_restful import inputs
int_range :整数的返回最小1最大5 整数的返回
rp.add_argument('a', required=True, help='参数必须传入',type=inputs.int_range(1, 5))
natural 自然数 0...10
rp.add_argument('a', required=True, help='参数必须传入',
type=inputs.natural)
positive 正整数
rp.add_argument('a', required=True, help='参数必须传入',
type=inputs.positive)
regex 传入正则表达式
rp.add_argument('a', required=True, help='参数必须传入',
type=inputs.regex(r'\d'))
url 传入url
rp.add_argument('a', required=True,
type=inputs.url)
自定义类型
def mobile(mobile_str):
'''
:param mobile_str: 接受被验证的参数(接受参数)
:return: 返回验证过的数据,如果错误就抛出异常
'''
if re.match(r'^1[3-9]\d{9}$',mobile_str):
return mobile_str
else:
raise ValueError('{} 格式不正确'.format(mobile_str))
rp.add_argument('a', required=True,type=mobile)
5.指明参数传递的位置 location
rp.add_argument('a', required=True,
type=int,location='form')
json files cookies headers args form 等位置进行传参
可以指明多个属性 location = [json,files]
使用序列化工具返回json格式
可以直接返回字典类型转为json格式给前端
把模型类转换字典,指定需要的内容。
工具:marshal
from flask_restful import marshal_with,marshal
marshal_with : 以视图装饰器的形式进行返回数据,对原始的marshl进行封装
marshal :直接返回数据
from flask import Flask
from flask_restful import Resource, Api, marshal_with, fields(定义类型), marshal
app = Flask(__name__)
# 指明返回数据的类型,指明以后数据会根据这个指明的类型进行转换
resouecr_fields = {
'name': fields.String,
'age': fields.Integer,
'address': fields.String
}
class UserInfo(Resource):
# @marshal_with(resouecr_fields,envelope='data)
# def get(self):
# 如果数据少传,就会根据少的字段赋值为null
# return {'name':'wkx','age':123}
def get(self):
# 效果和装饰器一样的
data = {'name': 'wkx', 'age': 123}
return marshal(data, resouecr_fields,envelope='data') # ,需要将返回前端的参数给传入到marshal中
api = Api(app)
api.add_resource(UserInfo, '/')
if __name__ == '__main__':
app.run(debug=True)
# envelope的参数意思就是将返回的参数内嵌到一个字典中
{
"data": {
"name": "wkx",
"age": 123,
"address": null
}
}
定制返回的json数据
from flask import make_response, current_app
from flask_restful.utils import PY3
from json import dumps
# 这个是restful中api中的提供的一个带参数的装饰器,允许定制返回数据的呈现格式
# 需要经过这里转变为json返回给前端
@api.representations('application/json')
def handle_json(data, code, headers):
'''
:param data: 接受视图的返回字典数据(需要返回前端)
:param code: 想返回的状态码
:param headers: 返回的表头
:return: 返回给前端的数据
'''
# 如果传入的数据,没有带message 就给它包裹一层
if 'message' not in data:
data = {
'message': 'OK',
'data': data
}
# 原代码不动
settings = current_app.config.get('RESTFUL_JSON', {})
if current_app.debug:
settings.setdefault('indent', 4)
settings.setdefault('sort_keys', not PY3)
dumped = dumps(data, **settings) + "\n"
resp = make_response(dumped, code)
resp.headers.extend(headers or {})
return resp
调用原代码 进行原始的封装,该原来的原代码
标签:__,return,name,Flask,app,flask,add,Api,Restful
From: https://www.cnblogs.com/kaixinblog/p/17878637.html