2021-11-07 flask api restful

  1. 首先,安装一个postman来测试备用,这玩意非常的难在官方下载,其他非官方渠道往往都不稳定我就不贴连接了免得失效了也是白弄,自己找自己下看运气。
  2. 然后是flask-restful
    flask-restful的文档传送门
  3. 安装
pip install flask-restful

4.使用API首先在扩展中导入,exts文件下的init.py中,因为数据库和API配合使用,而前端都是常用的我就一起都放这里了

#数据库
from flask_sqlalchemy import SQLAlchemy
db =SQLAlchemy()
#前段框架
from flask_bootstrap import Bootstrap
bootstrap=Bootstrap()
#api扩展
from flask_restful import Api
api=Api()

5.在工厂函数中绑定,一般我会在apps/init.py中构建这个函数

#配置文件导入
from setting import Config
#数据库
from exts import db #  这个DB是SQLAlchemy 制造的
#蓝图
from apps.view import user_bp # 引入蓝图的声明
#前段框架
from exts import bootstrap #
#表单
from flask_wtf import CSRFProtect
#Api导入
from exts import api
def create_app(app):
    app.config.from_object(Config)#环境配置
    app.register_blueprint(user_bp)  # 视图蓝图注册
    db.init_app(app)  # 这个是 SQLAlchemy 提供的绑定方法
    bootstrap.init_app(app=app) # 全段框架绑定
    csrf = CSRFProtect(app=app) # 全局令牌绑定
    api.init_app(app=app)  #api绑定
    return  app
  1. 在apps/views.py这个视图文件里边写api功能
#引入api扩展
from exts import api
#定义API类视图
from flask_restful import Resource  #引入这个特殊类在类定义的时候继承
#定义api功能类,记得要继承Resource
class UserResource(Resource):
    # get 请求
    def get(self):
        return {'msg':'GETgaoke'}
    # post 请求
    def post(self):
        return {'msg':'POSTgaoke'}
    # put 请求
    def put(self):
        return {'msg':'PUTgaoke'}
    # delete 请求
    def delete(self):
        return {'msg':'DELTETgaoke'}
#最后,务必要将定义的类通过add_resource方法添加入api
api.add_resource(UserResource,'/user')

这里注意这个api.add_resource(UserResource,'/user')写在视图文件里在每个功能类最后执行添加过程,如果把这个玩意弄到工厂函数中去添加则无效,简单说就写这里就像路由装饰器它写前面,这个功能和路由装饰器类似,他写后面.

上面提供了四个方法,GET方法浏览器直接访问就可以,其他方法需要借助POSTMAN测试,这里注意,如果开启了wtf-form表单则并开启了全局token验证,则api的 get意外三个方法都会显示 token丢失。我下面记录一个关闭验证的方法,就是在配置文件中加一句WTF_CSRF_CHECK_DEFAULT = False #这个关闭所有表单的验证,配置文件如下:

class Config(object):
    DEBUG=1
    SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:ga****622@47.1*5.7*.1**:3306/ckck01'
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SECRET_KEY = 'sdfasdf2312asdf'  #session的随机种子也是WRF-Form的令牌种子
    EVN='development'
    WTF_CSRF_CHECK_DEFAULT = False #这个关闭所有表单的验证

至此,最简API搭建出来,下面配合数据库:

~~~~~~~~fields的内容,输出格式化

这里的逻辑是先构建一个输出格式字典,然后在方法前添加一个装饰器把字典传装饰器里
下面这个是输出格式字典,这个格式有几个参数 attribute=‘name’ default=‘默认值’

from flask_restful import fields #输出格式化的类型
out_format= {
    'id':fields.Integer,
    'username':fields.String,
    'password':fields.String,
    'udatetime':fields.DateTime
}

这个格式有几个参数 attribute=‘name’ default='默认值'他俩的意思一个是隐藏数据库字段名字:如下列子中前段看到和拿到的密码是pwd的值而我们后端数据库中字段名字是password,如果没有attribute参数则必须把数据库字段暴露给前端。

另一个是没取到值就默认输出的内容。

out_format= {
    'id':fields.Integer,
    'name':fields.String(attribute='username',  default='默认值'),
    'pwd':fields.String (attribute='password'),
    'udatetime':fields.DateTime
}

下面是装饰器

from flask_restful import marshal_with #引入这个装饰器用来包装输出格式
class UserResource(Resource):
    # get 请求
    @marshal_with(out_format)####把上面的构建的字典传进来
    def get(self):
        u_api=Userapi.query.all()#查询数据库,获取数据集合
        return u_api 

至此,输出都会按照定义好的格式进行输出。

传参—get方法之尖括号

class UserSimResource(Resource):                  #注意1:类要继承
    def get(self,id):                             #注意2:接收传参
        return {'msg':'haha,get:%s'%str(id)}
api.add_resource(UserSimResource,'/user/<int:id>')#注意3:路由绑定以及传参格式设定

带上数据库和格式化输出则下面这样~

############## 单个查询
class UserSimResource(Resource):
    @marshal_with(out_format)
    def get(self,id):
        xx=Userapi.query.get(id)
        return xx
    def put(self,id):
        pass
api.add_resource(UserSimResource,'/user/<int:id>')
关于~ endpoint=的使用,它仅仅是在路由上给这个路由起个别名的意思比如下面这个路由,本来叫UserSimResource 加了endpoint后就叫user1 ,具体用法和FLAKS视图差不多都是用url_for('user1')来找路由
api.add_resource(UserSimResource,'/user/<int:id>',endpoint='user1')

传参与验证reqparse

这个传参验证逻辑是

  1. 建立一个解析对象parser1= reqparse.RequestParser()
  2. 把要盯梢的名字添加进入解析对象,同时还可以加入验证和报错消息parser1.add_argument('password',required=True,help='必须输入值')
  3. 在具体的请求中获取带数据的对象args=parser1.parse_args()
  4. 取出具体名字的值username=args.get('username')
from flask_restful import reqparse   #传参验证总司令

parser1= reqparse.RequestParser()  #解析对象
parser1.add_argument('username',type=str)   #把要获取的名字加进来进行声明,逗号后面基本都是验证
parser1.add_argument('password',required=True,help='必须输入值')   #required=True意思是必须传值,否则报错,报错内容由help=‘内容’来负责
#parser1.add_argument('password',type=int)   #这个type可以指定类型

#
class UserResource(Resource):
    # get 请求
    @marshal_with(out_format)
    def get(self):
        u_api=Userapi.query.all()
        return u_api
    # post 请求
    def post(self):
        args=parser1.parse_args() #获取数据
        username=args.get('username')
        password=args.get('password')
        user = Userapi()
        user.username=username
        user.password=password
        db.session.add(user)
        db.session.commit()
        return {'username':username,'password':password}

关于postman模拟POST请求

因为POST请求在Body里边所以记得按照下面进行选择,就可以传语句体的POST
请添加图片描述
此时,如果用拼接方式POST传值也是可以的,都能取到,只是路由上会拼上一堆东西很扎眼
请添加图片描述
如果,不允许拼接式POST传值则要:location = ['form'] 表示只允许表单POST方式提交

parser1= reqparse.RequestParser()  #解析对象
parser1.add_argument('username',type=str ,location = ['form'])   #把要获取的名字加进来
#进行声明,逗号后面基本都是验证,location = ['form']则不让拼接传值

这个location参数里边是列表,写什么方式什么方式可以进来比如:

parser1.add_argument('username',type=str ,location = ['form',‘args’])

就可以POST和GET ,其他的还有‘headers’,'cookies'

正则方法验证:

from flask_restful import  inputs 
parser1.add_argument('phone',type=inputs.regex(r'^1[356789]\d{9$}'))   
#这个type可以指定类型,inputs.regex()是正则方法验证
#这个正则是验证手机号

列表式传入参数

如果要获取参数内部有,action='append')

parser1.add_argument('username',action='append')

‘username’他会以列表的形式接受多个参数:
类似 username=[‘曹操’,‘老大’,‘枭雄’] 这么个意思

接收文件(或者图片)的方式

  1. 引入类型
  2. 加入监听,指定类型并验证类型
from werkzeug.datastructures import FileStorage
parser1.add_argument('icon',type=FileStorage,location=['files'])
class UserResource(Resource):
  def post(self):
        args=parser1.parse_args()
        icon = args.get('icon')
        if icon :#icon如果有可以直接保存
            icon.save('./static/%s'%icon.filename) 
            #icon.filename可以拿到文件名,怕重名可以在名字里边加随机数字       

下面是比较标准的保存路径写法

upload_path=os.path.join(Config.UPLOAD_ICON_DIR,icon.filename)#标准化的保存路径写法
icon.save(upload_path)

保存路径到数据库

user = Userapi()
if icon :
	user.icon = os.path.join('upload',icon.filename)#保存到数据库,这里注意他的路径因为是基于FLASK调用的所以是在STATIC下的相对路径,上面那个是绝对路径

错误消息

  1. bundle_errors=True 这个参数默认是FALSE只报第一个错误,如果为True则报错的时候会一次性把所有错误报出来
parser1= reqparse.RequestParser(bundle_errors=True)  
#解析对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值