美文网首页
flask知识点

flask知识点

作者: 胖虎很可爱 | 来源:发表于2018-04-20 15:50 被阅读0次

    flask:

    新建项目使用:

    • 新建Flask项目
    • 导入Flask类
    from flask import Flask
    
    
    • Flask函数接收一个参数name,它会指向程序所在的模块
    app = Flask(__name__)
    
    
    • 装饰器的作用是将路由映射到视图函数index
    @app.route('/')
    def index():
        return 'Hello World'
    
    
    • Flask应用程序实例的run方法启动WEB服务器
    if __name__ == '__main__':
        app.run()
    

    初始化参数

    • import_name: 模块名
    • static_url_path: 静态文件访问前缀
    • static_folder: 默认‘static’
    • template_folder: 默认‘templates’

    配置参数

    • app.config.from_pyfile(“yourconfig.cfg”)
    • app.config.from_object()

    读取配置参数

    • app.config.get()
    • 在视图中 current_app.config.get()

    app.run的参数

    • app.run(host=”0.0.0.0”, port=5000, debug = True)

    请求方式限定

    使用 methods 参数指定可接受的请求方式,可以是多种

    @app.route('/',methods=['GET', 'POST'])
    def hello():
        return 'hello world'
    
    

    路由查找方式

    同一路由指向两个不同的函数,在匹配过程中,至上而下依次匹配(查找到就不在匹配)

    @app.route('/')
    def hello():
        return 'hello world'
    
    @app.route('/')
    def hello_flask():
        return 'hello flask'
    
    

    所以上面路由 / 输出的结果为 hello 函数的结果

    给路由传参示例

    - 大致原理是将参数强转为int, 如果成功, 则可以进行路由匹配
    - 如果参数无法转换成功, 就无法匹配该路由
    
    @app.route('/orders/<int:order_id>')
    def hello_world(order_id):
        print type(order_id) # 类型为int
        return 'hello world %d' % order_id
    

    重定向redirect示例

    方式一: 使用redirect

    from flask import redirect
    @app.route('/redirect')
    def redirect_demo():
        return redirect('http://www.baidu.com')
    
    

    方式二:使用redirect和url_for

    from flask import url_for
    @app.route('/redirect')
    def redirect_demo():
        # url_for: 根据传入的视图函数名, 找到对应的路由地址
        # 两者通常结合使用
        print url_for('index')
        return redirect(url_for('index'))
    

    返回JSON

    方式一: 使用json.dumps()

    - 仅仅是将字典转换为JSON格式的字符串. 
    - 返回的响应头Content-Type为text/html
    
    
    from flask import Flask,json
    @app.route('/json')
    def do_json():
        hello = {"name":"stranger", "say":"hello"}
        return json.dumps(hello)
    
        # 如果要实现和方式二一样的效果, 可以使用如下方式
        # return 第一个参数: 返回的数据, 第二个参数: 状态码, 第三个参数: 设置响应头信息
        # return json.dumps(json_info), 200, {'Content-Type': 'application/json'}
    
    

    方式二: 使用jsonify()

    - 除了将字典转换为JSON格式的字符串
    - 同时会设置响应头Content-Type为application/json
    - 建议使用jsonify, 前后端分离的项目中, 前后端都通过JSON进行数据交流
    
    
    from flask import Flask,json
    @app.route('/json')
    def do_json():
        hello = {"name":"stranger", "say":"hello"}
        return jsonify(hello)
    
    

    返回状态码示例

    在 Python 中返回状态码有两种方式实现:

    - 直接return 
        - 可以自定义返回状态码,可以实现不符合http协议的状态码,例如:error=666,errmsg='查询数据库异常',其作用是为了实现前后端数据交互的方便
    - abort方法
        - 只会抛出符合http协议的异常状态码,用于手动抛出异常
        - 具体讲解详见<异常捕获>一节
    
    @app.route('/')
    def hello_world():
        return 'hello world',666
    

    正则路由示例

    在web开发中,可能会出现限制用户访问规则的场景,那么这个时候就需要用到正则匹配,限制访问,优化访问. 这一点Flask没有Django方便, 在实际开发中, 通常都需要自己定义一个正则路由转换器

    • 导入转换器包
    from werkzeug.routing import BaseConverter
    
    
    • 自定义转换器并实现
    class Regex_url(BaseConverter):
        def __init__(self,url_map,*args):
            super(Regex_url,self).__init__(url_map)
            self.regex = args[0]
    
    
    • 将自定义转换器类添加到转换器字典中
    app.url_map.converters['re'] = Regex_url
    
    
    • 使用re转换器并传入正则表达式来实现路由的匹配
    @app.route('/user/<re("[a-z]{3}"):id>')
    def hello_world(id):
        return 'hello %s' %id
    

    自带几种转换器

    系统实际提供了6个转换器可供开发者使用. 当使用<>来接收参数时, 就会调用系统默认的转换器进行匹配工作.

    - 默认的就是UnicodeConverter, 所以不填转换器名称, 或者使用default、string都是一样的. 
    - 默认将参数当做普通字符串对待.
    
    DEFAULT_CONVERTERS = {
        'default':          UnicodeConverter,
        'string':           UnicodeConverter,
        'any':              AnyConverter,
        'path':             PathConverter,
        'int':              IntegerConverter,
        'float':            FloatConverter,
        'uuid':             UUIDConverter,
    }
    

    获取请求中的数据

    flask中代表当前请求的是request对象:

    常用的属性如下:

    属性 说明 类型
    method 记录请求使用的HTTP方法 GET/POST
    headers 记录请求中的报文头 EnvironHeaders
    url 记录请求的URL地址 string
    cookies 记录请求中的cookie信息 Dict
    args 记录请求中的查询参数 MultiDict
    form 记录请求中的表单数据 MultiDict
    data 记录请求的数据,并转换为字符串 *
    files 记录请求上传的文件 *

    abort 方法

    抛出一个给定状态代码的 HTTPException,例如想要用一个页面未找到异常来终止请求,你可以调用 abort(404)。

    参数: code – HTTP的错误状态码

    abort(404)
    
    

    只能抛出HTTP协议的状态码

    errorhandler 装饰器

    注册一个错误处理程序,当程序抛出指定错误状态码的时候,就会调用该装饰器所装饰的方法

    参数:code_or_exception – HTTP的错误状态码或指定异常

    • 例如统一处理状态码为500的错误给用户友好的提示:
    @app.errorhandler(404)
    def internal_server_error(e):
        return '网页找不到了', 404
    

    请求钩子

    在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如:在请求开始时,建立数据库连接;在请求结束时,指定数据的交互格式。为了让每个视图函数避免编写重复功能的代码,Flask提供了通用设施的功能,即请求钩子。

    请求钩子是通过装饰器的形式实现,类似于Django的中间件. Flask支持如下四种请求钩子:

    • before_first_request:在处理第一个请求前运行。
    • before_request:在每次请求前运行。
    • after_request:如果没有未处理的异常抛出,在每次请求后运行。
    • teardown_request:在每次请求后运行,即使有未处理的异常抛出。
    @app.route('/')
    def hello_world():
        print '这里正在执行处理逻辑'
        return 'Hello World!'
    
    
    # 在处理第一个请求前运行. 应用场景: 比如连接数据库操作
    @app.before_first_request
    def before_first_request():
        print 'before_first_request'
    
    # 在每次请求前运行。应用场景: 比如对数据做效验. 如果数据有问题, 可以直接返回. 就不会再去执行对应的视图函数
    @app.before_request
    def before_request():
        print 'before_request'
        # return 'hehe'
    
    # 如果没有未处理的异常抛出, 在每次请求后运行。应用场景: 比如拼接响应头信息. 让所有json.dumps()的数据, 统一增加Content-Type为application/json
    @app.after_request
    def after_request(response):
        print 'after_request'
        response.headers['Content-Type'] = 'application/json'
        return response
    
    
    # 在每次请求最后运行,即使有未处理的异常抛出。 可以捕获到异常信息
    @app.teardown_request
    def teardown_request(e):
        print 'teardown_request %s' % e
    

    状态保持

    • 因为http是一种无状态协议,不会保持某一次请求所产生的信息,如果想实现状态保持,在开发中解决方式有:
      • cookie:数据存储在客户端,节省服务器空间,但是不安全
      • session:会话,数据存储在服务器端

    设置cookie

    from flask imoprt Flask,make_response
    @app.route('/cookie')
    def set_cookie():
        resp = make_response('this is to set cookie')
        resp.set_cookie('username', 'hello')
        return resp
    

    获取cookie

    from flask import Flask,request
    #获取cookie
    @app.route('/request')
    def resp_cookie():
        resp = request.cookies.get('username')
        return resp
    

    session数据的设置与获取

    session:请求上下文对象,用于处理http请求中的一些数据内容

    记得设置secret_key: app.secret_key = 'changhao' secret_key的作用:https://segmentfault.com/q/1010000007295395

    from flask import Flask, session, redirect, url_for
    @app.route('/set_session')
    def set_session():
        session['username'] = 'hello'
        return redirect(url_for('get_session'))
    
    @app.route('/get_session')
    def get_session():
        return session.get('username')
    

    Flask的session存放位置

    flask和之前用过的其他框架有一点不同的是,它的session默认是完全保留在客户端浏览器中的,也就是说往flask的session中写入数据,最终这些数据将会以json字符串的形式,经过base64编码写入到用户浏览器的cookie里,也就是说无须依赖第三方数据库保存session数据,也无需依赖文件来保存

    注意:在实际的开发过程中还是需要把session存放在redis中,通过flask-session扩展实现。

    命令行启动服务器

    通过使用Flask-Script扩展,我们可以在Flask服务器启动的时候,通过命令行的方式启动。

    from flask import Flask
    from flask_script import Manager
    
    app = Flask(__name__)
    # 把 Manager 类和应用程序实例进行关联
    manager = Manager(app)
    
    @app.route('/')
    def index():
    return '床前明月光'
    
    if __name__ == "__main__":
    manager.run()
    
    

    script的命令行参数

    传入参数而不仅仅通过app.run()方法中传参,比如我们可以通过:

    python hello.py runserver -host ip地址
    

    数据库:

    安装 flask-sqlalchemy
    pip install flask-sqlalchemy
    
    

    如果连接的是mysql数据库,需要安装mysqldb

    pip install flask-mysqldb
    

    使用Flask-SQLAlchemy管理数据库

    在Flask-SQLAlchemy中,数据库使用URL指定,而且程序使用的数据库必须保存到Flask配置对象的SQLALCHEMY_DATABASE_URI键中。

    Flask的数据库设置:

    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/test'
    

    其他设置:

    # 动态追踪修改设置,如未设置只会提示警告, 不建议开启
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    # 查询时会显示原始SQL语句
    app.config['SQLALCHEMY_ECHO'] = True
    

    flask-数据库的基本使用:

    db.session.add(role)    添加到数据库的session中
    db.session.add_all([user1, user2]) 添加多个信息到session中
    db.session.commit()     提交数据库的修改(包括增/删/改)
    db.session.rollback()   数据库的回滚操作
    db.session.delete(user) 删除数据库(需跟上commit)
    

    数据库迁移:

    #coding=utf-8
    from flask import Flask
    
    from flask_sqlalchemy import SQLAlchemy
    from flask_migrate import Migrate,MigrateCommand
    from flask_script import Shell,Manager
    
    app = Flask(__name__)
    manager = Manager(app)
    
    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/Flask_test'
    db = SQLAlchemy(app)
    
    #第一个参数是Flask的实例,第二个参数是Sqlalchemy数据库实例
    migrate = Migrate(app,db) 
    
    #manager是Flask-Script的实例,这条语句在flask-Script中添加一个db命令
    manager.add_command('db',MigrateCommand)
    
    if __name__ == '__main__':
        manager.run()
    
    创建迁移仓库
    #这个命令会创建migrations文件夹,所有迁移文件都放在里面。
    python database.py db init
    
    创建迁移脚本
    • 自动创建迁移脚本有两个函数
      • upgrade():函数把迁移中的改动应用到数据库中。
      • downgrade():函数则将改动删除。
    • 自动创建的迁移脚本会根据模型定义和数据库当前状态的差异,生成upgrade()和downgrade()函数的内容。
    • 对比不一定完全正确,有可能会遗漏一些细节,需要进行检查
    python database.py db migrate -m 'initial migration'
    
    更新数据库
    python database.py db upgrade
    
    返回以前的版本

    可以根据history命令找到版本号,然后传给downgrade命令:

    python app.py db history
    
    输出格式:<base> ->  版本号 (head), initial migration
    
    • 回滚到指定版本
    python app.py db downgrade 版本号
    
    实际操作顺序:
    • 1.python 文件 db init
    • 2.python 文件 db migrate -m"版本名(注释)"
    • 3.python 文件 db upgrade 然后观察表结构
    • 4.根据需求修改模型
    • 5.python 文件 db migrate -m"新版本名(注释)"
    • 6.python 文件 db upgrade 然后观察表结构
    • 7.若返回版本,则利用 python 文件 db history查看版本号
    • 8.python 文件 db downgrade(upgrade) 版本号

    restful

    一、域名:

    将api部署在专用域名下:

    http://api.example.com
    

    或者将api放在主域名下:

    http://www.example.com/api/
    
    二、版本:

    将API的版本号放在url中。

    http://www.example.com/app/1.0/info
    http://www.example.com/app/1.2/info
    
    三、路径:

    路径表示API的具体网址。每个网址代表一种资源。 资源作为网址,网址中不能有动词只能有名词,一般名词要与数据库的表名对应。而且名词要使用复数。

    示例:

    #获取单个商品
    http://www.example.com/app/goods/1
    
    #获取所有商品
    http://www.example.com/app/goods
    
    四、使用标准的HTTP方法:

    对于资源的具体操作类型,由HTTP动词表示。 常用的HTTP动词有四个。

    GET     SELECT :从服务器获取资源。
    POST    CREATE :在服务器新建资源。
    PUT     UPDATE :在服务器更新资源。
    DELETE  DELETE :从服务器删除资源。
    
    五、服务器返回的数据格式,应该尽量使用JSON,避免使用XML。

    相关文章

      网友评论

          本文标题:flask知识点

          本文链接:https://www.haomeiwen.com/subject/ahqzkftx.html