flask框架学习(三)——Flask RESTful

Flask RESTful

why learn it?
Flask_RESTful —>快速构建REST API的Flask扩展
安装

pip install flask_restful

案列:

from flask import Flask
from flask_restful import Resouce, Api

app = Flask(__name__)
api = Api(app)

class DemoResource(Resource):
    def get(self):
        return {'hello': 'world'}

        def post(self):
        return {'msg': 'post hello world'}

api.add_resource(DemoResource, '/')

对比原生flask:

  • 增加一个RESTful提供的Api类对象,用于收集类视图的注册信息。
  • 收集:创建类视图——>类中的不同方法对应不同的请求资源。类继承自:Resource,返回**字典:**类型数据。
  • 为类视图绑定路由Add_resource(类视图。‘/路由信息’)

视图

1. 路由

  • 添加:add_resource()
  • 起名:endpoint=
app.add_resource(DemoResource, '/demo', endpoint = ”demo“)

2. 蓝图中使用

from flask import Flask,Blueprint
from flask_restful import Api, Resource

app = Flask(__name__)

user_bp = Blueprint('user',__name__)

user_api = Api(user_bp)

class UserProfileResource(Resource):
	def get(self):
		return {'msg':'get user profile'}

user_api.add_resource(UserProfileResource,'/user/profile', endpoint='userprofile')

app.register_blueprint(user_bp)

对比app中 使用restful和蓝图

  1. 使用蓝图
  • 创建蓝图对象 : bp = Blueprint(‘name’,name)
  • 用蓝图对象装饰器去装饰方法路由 :@bp.route(’’)
  • 在主程序中注册蓝图:register_blueprint(bp)
  1. 蓝图中使用restful
  • api = Api(bp) -->创建api对象时接收的参数不再时app(主程序),而是bp(蓝图)
  • 采用restful 类视图函数而不是方法,不再使用装饰器
  • api = Api(bp)------>收集数据------>bp
  • api = Api(app)------收集数据------->全局flask

3. 装饰器
添加装饰器:method_decorators

  1. 为所有类视图添加相同装饰器
  • 定义装饰器(1个或多个)
  • 在类视图中添加装饰器
class DemoResource(Resource)
	method_decorators = [decorator1, decorator2]
	def ...
  1. 为不同类视图添加不同装饰器
method_decorators = {
          'get': [decorator1, decorator2],
          'post': [decorator1]
      }

请求

flask_restful ----> RequestParser–>(检验、转换请求数据。)
步骤:

  1. 导包:from flask_restful import reqparse
  2. 创建requestparser对象:parser = reqparse.RequestParser()
  3. 向requestparser对象添加需要检验或转换的参数声明。add.argument()
  4. 启动检验:parse_args()
  5. 从结果中获取参数:—>字典/对象属性。
    args.rate or args[‘rate’]
from flask_restful import reqparse

parser = reqparse.RequestParser()
parser.add_argument('rate', type=int, help='Rate cannot be converted', location='args')
parser.add_argument('name')
args = parser.parse_args()

参数说明
第三步,向requestparser对象中添加需要转化、检验的请求数据。

  1. required
    描述一个请求时是否一定需要携带参数---->False
    True:强制携带,未携带是返回状态码400
    False:不要求强制,未携带取出None
  2. help
    请求参数校验错误返回错误信息的描述
rp.add_argument('a',required=True, help='missing a param')
  1. action
    描述请求对象中出现多个同名参数的处理方式
  • action = ‘store’ -------->保留第一个(默认)
  • action= ‘append’
    ------->以列表追加保存所有同名参数的值—>like= [‘画画’, ‘唱歌’,‘摄影’]
  1. type
    描述参数应该匹配的类型。
  • python标准数据类型
rp.add_argument('a', type = int, required=True, help='miss a param', action='append')
  • Flask-RESTful---->检验参数类型方法----->flask_resetful.inputs
    1. url
    2. regex(自定义正则表达式)
    3. natural 自然数0、1、2、3…
    4. positive 正整数 1、2、3
    5. int_range(low, high) 整数范围

(2)

from flask_restful import inputs
rp.add_argument('a',type = inputs.regex(r'^\d{2}&'))

(5)

 rp.add_argument('a', type = inputs.int_range(1, 10))
  1. boolean
  • 自定义
def mobile(mobile_str):
    """
    检验手机号格式
    :param mobile_str: str 被检验字符串
    :return: mobile_str
    """
    if re.match(r'^1[3-9]\d{9}$', mobile_str):
        return mobile_str
    else:
        raise ValueError('{} is not a valid mobile'.format(mobile_str))

rp.add_argument('a', type=mobile)
  1. location
    描述参数在请求数据中应该出现的位置
    location:
  • form ------>请求数据的----->表单
  • args----------------------------->querystring
  • headers------------------------>request headers
  • cookies-------------------------> http cookies
  • json------------------------------>json
  • files------------------------------>uploads

ofcurse! ------可指明多个位置

parser.add_argument('text',location=['headers','json'])

响应

序列化返回

Flask-RESTful提供了marshal---->将数据序列化为特定格式的字典数据---->作为视图的返回值。
任何对象--------->字典

  1. 装饰器用法:@marshal_with(resource_fields,envelope=‘resource’)
    • 导包:from flask_ restful import Resource, fields, marshal_withmarshal
    • 指定序列化字段:xx = {‘name’ : fields.type}
    • marshal装饰器(marshal_with)为restful类视图中的get方法添加装饰器。
    • 视图函数,获取某一对象,将得到的对象经过序列化返回。
 from flask_restful import fields,marshal,marshal_with,Resource

resource_fields = {
	'name':fields.String,
	'age':fields.Integer
}


class DemoResource0(Resource):
	@marshal_with(resource_fields,envelope='data')
	def get(self):
		user = User.object.get(id=1)
		return user


class DemoResource1(Resource):
	def get(self):
		user = User.object.get(id=1)
		# 除了指明字段和envelope之外,还需指明要处理的对象是谁。
		return marshal(user, resource_fields,envelope='data')

envelope: 信封--------->{‘data’:{‘user’:‘小王’,‘age’:18}}


  1. marshal()返回

定制返回的json格式——representation装饰器

需求:规定接口返回的json数据具有统一的格式

{"message": "描述信息", "data": {要返回的具体数据}}

representation<-----------------Flask-RESTful的Api对象------------>定制返回数据的呈现格式。
representation:相当于哟个钩子,允许你挂个函数——指定返回数据格式

@api.representation('application/json')
def func()
	处理内容
	...

在视图函数中得到得返回数据,并不立刻直接返回给客户端,而是先经过被representation装饰得函数之后再返回。
method:
修改flask_restful.representations.json代码:

from flask import make_response, current_app
from flask_restful.utils import PY3
from json import dumps


def output_json(data, code, headers=None):
    """Makes a Flask response with a JSON encoded body"""

 # 此处为自己添加***************
    if 'message' not in data:
    data = {
        'message': 'OK',
        'data': data
    }
    # **************************


    settings = current_app.config.get('RESTFUL_JSON', {})

    # If we're in debug mode, and the indent is not set, we set it to a
    # reasonable value here.  Note that this won't override any existing value
    # that was set.  We also set the "sort_keys" value.
    if current_app.debug:
        settings.setdefault('indent', 4)
        settings.setdefault('sort_keys', not PY3)

    # always end the json dumps with a new line
    # see https://github.com/mitsuhiko/flask/pull/1262
    dumped = dumps(data, **settings) + "\n"

    resp = make_response(dumped, code)
    resp.headers.extend(headers or {})
    return resp

你可能感兴趣的:(python,Flask,Python)