您的位置:首页 > 编程语言 > Python开发

三十一、python学习之Flask框架(三)视图:路由、上下文、Flask-Script扩展

2018-10-17 21:32 337 查看
版权声明:浅弋、璃鱼的原创 https://blog.csdn.net/qq_35709559/article/details/83111051

一、装饰器路由的具体实现

1.Flask框架路由实现


Flask有两大核心:Werkzeug和Jinja2

  • Werkzeug实现路由、调试和Web服务器网关接口
  • Jinja2实现了模板。

Werkzeug是一个遵循WSGI协议的python函数库

  • 其内部实现了很多Web框架底层的东西,比如request和response对象;
  • 与WSGI规范的兼容;支持Unicode;
  • 支持基本的会话管理和签名Cookie;
  • 集成URL请求路由等。

2. Flask框架中实现route的方法:

Werkzeug库的 routing 模块负责实现 URL 解析。不同的 URL 对应不同的视图函数,routing模块会对请求信息的URL进行解析,匹配到URL对应的视图函数,执行该函数以此生成一个响应信息。

routing模块内部有:

  • Rule类
  • 用来构造不同的URL模式的对象,路由URL规则
  • Map类
    • 存储所有的URL规则和一些配置参数
  • BaseConverter的子类
    • 负责定义匹配规则
  • MapAdapter类
    • 负责协调Rule做具体的匹配的工作

    二、上下文:

    1.上下文:

    相当于一个容器,保存Flask程序运行过程中的一些信息。
    Flask中有两种上下文:

    • 请求上下文;
    • 应用上下文;

    2.请求上下文(request Context):

    在 flask 中,可以直接在视图函数中使用 request 这个对象进行获取相关数据,而 request 就是请求上下文的对象,保存了当前本次请求的相关数据,请求上下文对象有:request、session

    • request
      – 封装了HTTP请求的内容,针对的是http请求。举例:user = request.args.get(‘user’),获取的是get请求的参数。
    • session
      – 用来记录请求会话中的信息,针对的是用户信息。举例:session[‘name’] = user.id,可以记录用户信息。还可以通过session.get(‘name’)获取用户信息。

    2.1.request获取请求参数:

    request 就是flask中代表当前请求的 request 对象,其中一个请求上下文变量(理解成全局变量,在视图函数中直接使用可以取到当前本次请求)。
    常用的属性如下:

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

    代码演示:

    request常用的属性:args、from、method、files、headers、url

    args属性的代码实例:

    # GET请求:arg查询字符串,获取请求url地址中的查询字符串参数
    # 127.0.0.1:5000/args_demo?name=hahah&age=18 使用?号查询,条件使用&分隔
    @app.route("/args_demo", methods = ["POST", "GET"])
    def demo_args():
    if request.method == "GET":
    name = request.args.get('name')
    age = request.args.get('age')
    print(name, age)
    return "GET response..."
    else:
    # 如果是post请求,接收的是表单数据
    itcast = request.form.get('itcast')
    age = request.form.get('age')
    print(itcast, age)
    return 'POST response...'

    files属性的代码实例:

    # files属性:
    @app.route("/images", methods=['GET', 'POST'])
    def get_image():
    # 获取图片使用post方法,通过files属性获取
    image = request.files.get("image")
    # 保存图片
    image.save("./demo01.jpg")
    return 'save image success...'

    url属性的代码实例

    # url属性
    # 测试用例:127.0.0.1:5000/
    @app.route("/", methods=["GET", "POST"])
    def param_url():
    print("请求方法:" + str(request.method))
    print("请求头:" + str(request.headers))
    print("请求url:" + str(request.url))
    return "请求url..."

    3.应用上下文:

    它的字面意思是 应用上下文,但它不是一直存在的,它只是request context 中的一个对 app 的代理(人),所谓local proxy。它的作用主要是帮助 request 获取当前的应用,它是伴 request 而生,随 request 而灭的。

    应用上下文对象有:

    • current_app;
    • g变量;

    3.1 current_app

    应用程序上下文,用于存储应用程序中的变量,可以通过current_app.name打印当前app的名称,也可以在current_app中存储一些变量,例如:

    • 应用的启动脚本是哪个文件,启动时指定了哪些参数;
    • 加载了哪些配置文件,导入了哪些配置;
    • 连了哪个数据库;
    • 有哪些public的工具类、常量;
    • 项目中用来记录项目日志;
    • 应用跑再哪个机器上,IP多少,内存多大;
      current_app.name
      current_app.test_value=‘value’

    3.2 g变量:

    g 作为 flask 程序全局的一个临时变量,充当者中间媒介的作用,我们可以通过它传递一些数据,g 保存的是当前请求的全局变量,不同的请求会有不同的全局变量,通过不同的thread id区别。
    g.name=‘abc’

    注意:不同的请求,会有不同的全局变量

    3.3 两者区别:

    • 请求上下文:保存了客户端和服务器交互的数据
    • 应用上下文:flask 应用程序运行过程中,保存的一些配置信息,比如程序名、数据库连接、应用信息等

    上下文中的对象只能在指定上下文中使用,超出范围不能使用 请求上下文和应用上下文原理实现:
    参考文章:https://segmentfault.com/a/1190000004223296

    三、Flask-Script扩展:

    通过使用Flask-Script扩展,我们可以在Flask服务器启动的时候,通过命令行的方式传入参数。而不仅仅通过app.run()方法中传参,比如我们可以通过:

    python hello.py runserver -host ip地址

    以上代码告诉服务器在哪个网络接口监听来自客户端的连接。默认情况下,服务器只监听来自服务器所在的计算机发起的连接,即localhost连接。

    Flask-Scritp扩展包的作用:

    • 在终端中手动输入host和port等;
    • 进行数据库的迁移;
    • 自定义命令;

    3.2 使用语法:

    # !/usr/bin python3
    # coding=utf8
    from flask import Flask
    from flask_script import Manager
    
    app = Flask(__name__)
    app.config['DEBUG'] = True
    manage = Manager(app)
    
    @app.route("/")
    def index():
    return "hello world"
    
    if __name__ == '__main__':
    # app.run()
    
    # 启动服务器不用打开代码,可使用终端手动的启动服务,动态的传入host和port
    manage.run()

    启动方法:

    阅读更多
  • 内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: