美文网首页
2020-06-01--flask03--flask基础03

2020-06-01--flask03--flask基础03

作者: program_white | 来源:发表于2020-06-01 23:02 被阅读0次

    本节内容

    • 请求钩子
    • request
    • 状态保持(cookie,session)
    • 上下文
    • flask_script
    • jinja2模板引擎

    请求钩子

    在flask中为避免代码的重复,flask提供了统一的接口可以添加这些处理函数,即请求钩子。

    请求钩子:
    交互过程中,有一些准备或扫尾工作需要:
    比如请求开始时要进行datebase的连接,auth的认证等
    请求结束的时候指定数据的交互格式。
    请求钩子通过 装饰器 实现的

    • before_first_request:在第一次请求之前调用(在处理第一个请求之前执行),可以在此方法内部做一些初始化操作
    • before_request:在每次请求之前执行,如果在某修饰的函数中返回了一个response,视图函数将不会被调用
    • after_request:在执行完视图函数之后调用,并且会把视图函所生成的响应传入,可以在此方法中对响应做最后一步的统一处理。ps:如果视图函数出错,则不执行该函数。
    • teardown_request:在每次请求之后执行,接收一个参数--错误信息。如果有相关的错误就会抛出。
    @app.before_first_request
    def before_first_request():
        print('before_first_request')
    
    @app.before_request
    def before_request():
        print('before_request')
    
    @app.after_request
    def after_request(response):
        print('after_request')
        #把响应内容header部分的Content-Type改为applcation/json
        response.headers['Content-Type'] = "application/json"
        return response
    
    @app.teardown_request
    def teardown_request(response):
        print('teardown_request')
    
    @app.route('/')
    def index():
        return 'index'
    

    运行:
    Content-type被更改:



    request

    状态保持

    http是一种无状态协议

    • 无状态: ----> 用户一次请求,浏览器,服务器无法知道之前用户做过什么。因为浏览器和服务器之间使用socket通信。

    对于无状态协议的理解,看做以下五条
    1、协议对于事务处理没有记忆能力
    2、对同一个url请求没有上下文关系
    3、每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求是无直接关系的,它不会受前面的请求应答情况直接影响,也不会直接影响后面的请求应答情况
    4、服务器中没有保存客户端的状态,客户端必须每次带上自己的状态去请求服务器

    5、人生若只如初见:比如商品加入购物车,重登后购物车里的东西无了

    cookie:数据存储在客户端,节省服务器空间,但是不安全
    session:会话,数据存储在服务器端

    cookie:

    #cookie
    from flask import Flask, make_response, request  # django中的httpresponse
    app = Flask(__name__)
    
    #设置cookie
    @app.route('/cookie')
    def set_cookie():
        resp = make_response('this is set cookie')
        resp.set_cookie('username','laoma',max_age = 3600)  #max_age:cookie事件
        return resp
    
    #获取cookie
    @app.route('/request')
    def get_cookie():
        response = request.cookies.get('username')  #获取之前设置的cookie
        return response
    
    if __name__ == '__main__':
        app.run()
    

    运行:



    过期时间默认为浏览器会话结束:



    注:我们可以自己设计cookie的时间(利用max_age关键字)设置时间之后,再次运行:

    访问:

    127.0.0.1:5000/request
    

    获取到cookie的值:


    session

    session会话主要用于存储敏感涉密信息,例如:个人信息、账户余额、验证码等问题,session依赖于cookie,在TensorFlow中,也会使用session尽管和web中的session有所不同,但也可理解为会话方式。

    #session 会话(重要信息),依赖于cookie
    #设置session
    @app.route('/index1')
    def index1():
        session['lefmoney'] = '99999'  #设置session的键和值
        return redirect(url_for('index'))          #重定向到index函数中
    
    app.secret_key = 'fdsofof'      #用于一些模块的 hash
    
    @app.route('/')
    def index():
        return session.get('lefmoney','none')     #默认为0
    

    Session, Cookies以及一些第三方扩展都会用到SECRET_KEY值,这是一个比较重要的配置值,应该尽可能设置为一个很难猜到的值,随机值更佳。随机的问题在于很难判断什么是真随机。一个密钥应该足够随机。你的操作系统可以基于一个密码随机生成器来生成漂亮的随机值,这个值可以用来做密钥;
    SECRET_KEY配置变量是通用密钥, 可在 Flask 和多个第三方扩展中使用. 如其名所示, 加密的强度取决于变量值的机密度. 不同的程序要使用不同的密钥, 而且要保证其他人不知道你所用的字符串.其主要作用应该是在各种加密过程中加盐以增加安全性。在实际应用中最好将这个参数存储为系统环境变量。当然我们也可以利用加密哈希,就是让cookie变得“安全”的字段。服务器向我们发送最新的会话数据之前,会结合我们的会话数据、当前时间戳以及服务器的私钥来计算哈希从而加密session,使得会话变得安全。
    快速入门中的 “ 会话”部分对应设置哪种服务器端机密提供了很好的建议。加密取决于机密;如果你没有设置要使用的加密服务器端密码,那么每个人都可以破坏你的加密;就像你计算机的密码一样。秘密加上要签名的数据用于创建签名字符串,使用密码哈希算法很难重新创建值;仅当你具有完全相同的机密且原始数据时,你才能重新创建此值,让Flask检测是否未经许可对任何内容进行了更改。由于Flask永远不会将秘密包含在发送给客户端的数据中,因此客户端无法篡改会话数据,并希望产生新的有效签名。
    Flask尽量使用该itsdangerous库来完成所有艰苦的工作;会话使用带有自定义JSON序列化程序的itsdangerous.URLSafeTimedSerializer类。

    运行:
    没有session:



    进入index1设置session:



    取到session:

    上下文

    • request context :请求上下文 -- 包含 cookie 和 session
      例如:resp = request.cookies.get()等获取上下文方式。
    • application context : 应用上下文 -- current_app 和 g

    current_app和g都属于应用上下文对象。
    1、current_app:表示当前运行程序文件的程序实例。
    2、g:(global) 处理请求时,用于临时存储的对象,每次请求都会重设这个变量。比如:我们可以获取一些临时请求的用户信息。

    当调用app = Flask(name)的时候,创建了程序应用对象app;
    request 在每次http请求发生时,WSGI server调用Flask.call();然后在Flask内部创建的request对象;
    app的生命周期大于request和g,一个app存活期间,可能发生多次http请求,所以就会有多个request和g。
    最终传入视图函数,通过return、redirect或render_template生成response对象,返回给客户端。

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

    @app.route('/')
    def index():
        print(current_app.name)
        return session.get('lefmoney','none')     #默认为0
    

    运行:
    打印出当前运行的文件名:


    flask_script

    首先安装flask_script

    pip install flask_script
    

    demo_flask_script.py:

    from flask_script import Manager
    from flask import Flask
    
    app = Flask(__name__)
    
    #Manager和app关联
    manager = Manager(app)
    
    @app.route('/')
    def index():
        return 'haha1'
    if __name__ == '__main__':
        manager.run()
    

    在terminal中:

    python demo_flask_script.py runserver -h 127.0.0.1 -p 5001
    

    可以使用命令行进行启动

    jijia2模板引擎

    参考Django,Jinja2的模板语法与Django的模板内容基本相似
    语法:

    • 变量取值{{ }}、
    • 控制结构{% %}、
    • 注释{# #}
      模板语言的选择:


    from flask import Flask,render_template
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
    
        #String
        my_str = 'zhangsan'
        #num
        my_num = 100
        #列表
        my_list = [i for i in range(9)]
        #字典
        my_dict = {'name':'老亚瑟','age':18}
        #使用render_template进行模板渲染
        #在django中使用的是render
        return render_template('temp_demo1.html',
                               my_str = my_str,
                               my_num = my_num,
                               my_list = my_list,
                               my_dict = my_dict
                               )
    if __name__ == '__main__':
        app.run()
    

    html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>jinja2</h1>
    游戏名:{{ my_str }}
    <br>
    数字:{{ my_num }}
    <br>
    列表:{{ my_list }}
    <br>
    字典:{{ my_dict }}
    <br>
    my_num +10 = {{ my_num + 10 }}
    <br>
    my_num + array[0] = {{ my_num + my_list[1] }}
    <br>
    {{ my_list.1 }}
    {{ my_list[1] }}
    <br>
    {{ my_dict['name'] }}
    {{ my_dict.name }}
    </body>
    </html>
    

    运行:


    相关文章

      网友评论

          本文标题:2020-06-01--flask03--flask基础03

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