Flask_Restful架构

  • 基于前后端分离的架构,让后端工程师能够利用flask把重心放在后端开发。
  • 什么是flask_restful
    • 每一个URI代表一个资源
    • 客户端和服务器之间,传递这种资源的某种表现层
    • 客户端通过四种HTTP动词 GET POST PUT DELETE PATCH, 对服务器端资源进行操作。

安装

pip3 install flask-restful

快速上手

  1. 创建api对象

    api = Api(app=app)
    api = Api(app=蓝图对象)
    
  2. 定义类视图

    from flask_restful import Resource
    
    class xxxApi(Resource):
      def get(self):
        pass
      
      def post(self):
        pass
      
      def put(self):
        pass
    
  3. 绑定

    api.add_resource(xxxApi, '/user')  # 将实现类和路由绑定
    

参数传入和endpoint

  • 参数传入是绑定在add_resource()中,在url后面定义传入参数的类型

    api.add_resource(UserSimpleResource, '/user/<int:uid>')
    
  • endpoint指定url的别名

    api.add_resource(UserResource, '/user', endpoint='all_user')
    # 可通过flask.url_for('all_user')  反向解析到对应的url
    

reqparse是什么鬼?

当你的信息为form-data形式进行表单提交时,或者进行分页的业务时,url可能会有如下的情况

http://127.0.0.1:5000/goods?id=18&page=3

如果我们想获取url上的参数时,就需要导入reqparse模块,并且可以通过参数对url的传输进行校验。

from flask_restful import reqparse

parser = reqparse.RequestParser()  # 解析对象
parser.add_argument('username', type=str, required=True, help='必须输入用户名', location=['form'])
parser.add_argument('password', type=inputs.regex(r'^\d{6,12}$'), required=True, help='必须输入密码', location=['form'])
parser.add_argument('phonenum', type=inputs.regex(r'^1[356789]\d{9}$'), required=False, location=['form'])
parser.add_argument('hobby', action='append')
parser.add_argument('icon', type=FileStorage, location=['files'])  # 上传图片固定传法
# url上的参数获取
args = parser.parse_args()
username = args.get('username')
password = args.get('password')
phonenum = args.get('phonenum')
# 解析完毕后,想用的时候就用这种方法去获取url的参数

当对某些参数做出了required的校验时,如果传入的信息不对,那么会返回json信息

{
    "message": {
        "password": "必须输入密码"
    }
}

URI

  • 根据restful的编码风格,希望能够在response中包含下个动作的路径,举个例子,比如商品列表要包含商品信息的详情页。那么,这个详情页的uri如何去实现呢?

  • 在这里,我们可以用到fields.Url('url别名', absolute=True),来进行定义。

    # 首先我们需要定义两个序列化字段  商品列表字段  和   商品详情字段
    user_fields = {
        'id': fields.Integer,
        'username': fields.String,
        'pwd': fields.String(attribute='password'),
        'update_time': fields.DateTime
    }
    
    user_fields_1 = {
        'id': fields.Integer,
        'uri': fields.Url('single_user', absolute=True)  # 表示链接到详情页的业务,需要设置endpoint
    }
    
    业务逻辑...
    
    api.add_resource(UserResource, '/user', endpoint='all_user')
    
    api.add_resource(UserSimpleResource, '/user/<int:id>', endpoint='single_user')
    
    

复杂数据结构的输出

  • data必须是json格式

  • 如果直接返回不能有自定义的对象

  • 如果有这种对象,需要:marshal()marshal_with()帮助进行转换。

  • marshal(对象,对象的fields格式) 指的是字典的输出格式

    • marshal([对象, 对象], 对象的fields格式)
  • marshal_with()作为装饰器请求方法

    • 函数需要参数,参数就是数据输出的格式, 类型是dict

      user_fields = {
          'id': fields.Integer,
          'username': fields.String,
          'pwd': fields.String(attribute='password'),
          'update_time': fields.DateTime
      }
      
      user_friend_fields = {
          'username': fields.String,
          'nums': fields.Integer,
          'friends': fields.List(fields.Nested(user_fields))
      }
      
  • fields.Nested(fields.String) -----> ['aaa', 'bbb', 'ccc']

  • fields.Nested(user_fields) ------> user_fields是一个字典结构,将里面的每一个对象转成user_fields,里面放的是user对象

posted @ 2020-07-19 20:38  职业法师zcg  阅读(175)  评论(0编辑  收藏  举报