#Flask-RESTful
- restful api是用于在前端与后台进行通信的一套规范。使用这个规范可以让前后端开发变得更加轻松。以下将讨论这套规范的一些设计细节。
- 协议:
- 采用http或者https协议。
- 数据传输格式:
- 数据之间传输的格式应该都使用json
#快速入门
安装 pip install flask-restful
#初始化
from flask_restful import Api
api = Api()
def init_api(app):
api.init_app(app)
#注册路由
api.add_resource(UsersResource,'/users/')
api.add_resource(UserResource,'/user/<int:id>/')
#API视图函数
from flask_restful import Resource
class UsersResource(Resource):
def get(self):
return {'msg':'hello'}
class UserResource(Resource):
def get(self,id):
return {'msg':'hello %d' % id}
#输出
- 默认输出字典
- 可以直接进行序列化
- 如果包含对象默认会抛异常
- 对象不可JSON序列化
- 使用格式化工具
- marshal函数
- marshal_wwith装饰器
- 条件
- 格式
- 字典格式
- 允许嵌套
- value是fields.XXX
- 数据
- 允许任何格式
- 如果格式和数据完全对应,数据就是预期格式
- 如果格式比数据中的字段多,程序依然正常允许,不存在的字段是默认值
- 如果格式比数据中字段少,程序正常执行,少的字段不会显示
- 以格式的模板为主
- 结论
- 想要什么格式的返回
- 格式工具(模板)就是什么样的
- 和传入的额数据没什么直接关系
- 格式和数据的映射
- 格式中的字段名和数据中的名字需要一致
- 也可以手动指定映射
*Attribute = ‘字段名’
- 也可以对属性指定默认值
- default
- 指定默认值。值传递使用传进来的值
- 未传递,则使用默认值
title fields函数说明及使用
section Raw
format :a1,2016-06-22, 3d
output :a1,2016-06-22, 3d
调用 :a1,2016-06-22, 3d
将数据传递格式化工具的时候,先获取值output : after a1, 4d
再对值进行格式化format : a1,2016-06-22, 2d
1:1
section String
继承Raw :2016-06-22, 3d
将value进行格式化 :2016-06-22, 3d
转换成兼容格式 :2016-06-22, 3d
1:1
section Integer
继承Raw :2016-06-22, 3d
重写了初始化,将default=0 :2016-06-22, 3d
重写格式化直接将vlaue转换成int类型 :2016-06-22, 3d
1:1
section Boolean
继承Raw :2016-06-22, 3d
重写格式化,直接将value转换成bool :2016-06-22, 3d
1 : 1
section Nested
继承Raw :2016-06-22, 3d
重写output :2016-06-22, 3d
进行marshal序列化 :2016-06-22, 3d
section List
继承Raw :2016-06-22, 3d
重写output :2016-06-22, 3d
判断你的类型 :after a1, 4d
对不同的类型进行不同的处理 : after a1, 4d
dict直接进行处理 : 2016-06-26, 3d
list迭代处理 : 2016-06-26, 3d
重写format : 2016-06-22, 3d
进行格式化:after a1, 4d
#序列化uri
api =add_resource(GoodsResource,'/googs/<int>:id>/',endpoint='single_googs'
incident_fields = {
'uri':fields.Url('single_goods',absolute=True)
}
#序列化输出
from flask import request
from flask_restful import Resource, marshal_with, fields, abort
from App.models import Incidents
#序列化对象
info_fields = {
'g_name':fields.String,
'g_price':fields.Integer,
}
#嵌套对象序列化
post_info_fields = {
'status':fields.Integer,
'msg':fields.String,
'data':fields.Nested(info_fields)
}
#嵌套序列化对象列表
get_info_fields={
'status':fields.Integer,
'msg':fields.String,
'data':fields.List(fields.Nested(info_fields))
}
class GoodsResource(Resource):
@marshal_with(get_info_fields)
def get(self):
goods_list = Goods.query.all()
data = {
'status':200,
'msg':'ok',
'data':goods_list
}
return data
@marshal_with(post_info_fields)
def post(self):
g_id = request.form.get('g_id')
g_name = request.form.get('g_name')
g_price = request.form.get('g_price')
goods = Goods()
goods.g_id = g_id
goods.g_name = g_name
goods.g_price = g_price
if not goods.save():
abort(400)
data = {
'status':200,
'msg':'ok',
'data':goods
}
return data
@marshal_with(get_info_fields)
def delete(self,id):
goods = Goods.query.get(id)
if not goods:
abort(400)
if not goods.delete():
abort(400)
data ={
'status':201,
'msg':'delete success',
'data':goods
}
return data
#不使用装饰器
def put(self,id):
goods = Goods.query.get(id)
if not goods:
abort(404)
g_price = request.form.get('g_price')
g_name = request.form.get('g_name')
goods.g_name = g_name
goods.g_price = g_price
if not goods.save():
abort(400)
data = {
'msg':'put ok',
'status':200,
'data':goods
}
return marshal(data,get_info_fields)
@marshal_with(get_info_fields)
def patch(self,id):
goods = Goods.query.get(id)
if not goods:
abort(404)
g_price = request.form.get('g_price')
g_name = request.form.get('g_name')
goods.g_name = g_name or goods.g_name
goods.g_price = g_price or goods.g_price
if not goods.save():
abort(400)
data = {
'msg':'put ok',
'status':200,
'data':goods,
}
return data
- flask_restful中abort错误提示配置
* abort(404,message=‘Goods without corresponding id %d’ %id,msg=‘error’)
* 输出为JONS
{
"message": "Goods without corresponding id 1",
"msg": "error"
}
#输入
#Request Parsing
####RequestParser,使用过程
- 先定义一个RequestParser对象
- 向对象中添加字段
- 从对象中获取字段
parser = reqparse.RequestParser()
parser.add_argument('g_name')
parser.add_argument('g_price')
class GoodsResource(Resource):
@marshal_with(post_info_fields)
def post(self):
args = parser.parse_args()
g_name = args.get('g_name')
g_price = args.get('g_price')
goods = Goods()
goods.g_name = g_name
goods.g_price = g_price
if not goods.save():
abort(400)
data = {
'status':200,
'msg':'ok',
'data':goods
}
return data
{
"message": {
"g_name": "Please input g_name"
}
}
####对象在添加参数的时候,可以实现预校验
- 参数是否必须
- 数据类型
- 设置错误提示信息
- 接收多个值 action=‘append’
parser = reqparse.RequestParser()
parser.add_argument('mu',action='append')
args = parser.parse_args()
print(args.get('mu'))
#输出
[‘1’, ‘2’, ‘3’]
- 也可以在接受的时候指定别名 dest=‘name’
- 可以指定参数的来源