• 请求响应、session、闪现


    请求和响应

    from flask import Flask, request, render_template, redirect, make_response
    
    app = Flask(__name__)
    
    @app.route('/login.html', methods=['GET', "POST"])
    def login():
        return "登录"
    
    if __name__ == '__main__':
        app.run()
    

    请求相关信息

    # request.method	# 请求方式
    # request.args	    # 获取URL中的数据
    # request.form	    # 存放FormData中的数据。FormData是对象,Form表单是标签,当提交的时候,Form表单的标签会变成FormData提交。在Ajax中只能使用FormData
    # request.values	# post和get请求中的所有参数组成的CombinedMultiDict,通常用来查看数据
    # request.cookies	# 获取cookie中的数据
    # request.headers	# 获取请求头
    # request.path	    # 路由地址
    # request.url		# 访问的完整路径
    # request.host_url	# 将主机地址变成url	http://127.0.0.1:5000/
    # request.host	    # 主机地址	127.0.0.1:5000
    
    

    响应相关信息

    # return "字符串"
    # return render_template('html模板路径',**{})
    # return redirect('/index.html')
    
    dic = {'k1':'v1'}
    return json.dumps(dic)
    return jsonify(dic)
    
    # response = make_response(render_template('index.html'))
    # response是flask.wrappers.Response类型
    # response.delete_cookie('key')
    # response.set_cookie('key', 'value')
    # response.headers['X-Something'] = 'A value'
    # return response
    

    定制响应头的时候,可以封装到 make_response 中做操作

    from flask import Flask, url_for, make_response
    
    app = Flask(__name__)
    
    @app.route('/index', methods=['GET', 'POST'])
    def index():
        obj = make_response('Index')
        obj.headers['xxxx'] = '123'
        return obj
    
    if __name__ == '__main__':
        app.run()
    

    session

    除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名。要使用会话,需要设置一个密钥。

    • 设置:session['username'] = 'xxx'
    • 删除:session.pop('username', None)
    # 基本使用
    
    from flask import Flask, session, redirect, url_for, escape, request
     
    app = Flask(__name__)
     
    @app.route('/')
    def index():
        if 'username' in session:
            return 'Logged in as %s' % escape(session['username'])
        return 'You are not logged in'
     
    @app.route('/login', methods=['GET', 'POST'])
    def login():
        if request.method == 'POST':
            session['username'] = request.form['username']
            return redirect(url_for('index'))
        return '''
            <form action="" method="post">
                <p><input type=text name=username>
                <p><input type=submit value=Login>
            </form>
        '''
     
    @app.route('/logout')
    def logout():
        # remove the username from the session if it's there
        session.pop('username', None)
        return redirect(url_for('index'))
     
    # set the secret key.  keep this really secret:
    app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
    

    闪现

    有一个需求,一个值只能取一次

    from flask import Flask, session
    
    app = Flask(__name__)
    app.secret_key = "dghsagvds"
    
    @app.route('/set')
    def set():
        session['name'] = '湫兮如风'
        return "SET..."
    
    # 只能取一次
    @app.route('/get')
    def get():
        name = session.pop("name")
        print(name)
        return "GET..."
    
    if __name__ == '__main__':
        app.run()
    

    再取一次就会报错

    闪现可以完成这个需求

    from flask import Flask, flash, get_flashed_messages
    
    app = Flask(__name__)
    app.secret_key = "dghsagvds"
    
    @app.route('/set')
    def set():
        flash('湫兮如风')
        return "SET..."
    
    # 只能取一次
    @app.route('/get')
    def get():
        name = get_flashed_messages()
        print(name)
        return "GET..."
    
    if __name__ == '__main__':
        app.run()
    

    from flask import Flask, flash, get_flashed_messages
    
    app = Flask(__name__)
    app.secret_key = "dghsagvds"
    
    @app.route('/set')
    def set():
        flash('湫兮', "name")
        flash('如风')
        return "SET..."
    
    # 只能取一次
    @app.route('/get')
    def get():
        name = get_flashed_messages()
        print(name)
        return "GET..."
    
    if __name__ == '__main__':
        app.run()
    

    from flask import Flask, flash, get_flashed_messages
    
    app = Flask(__name__)
    app.secret_key = "dghsagvds"
    
    @app.route('/set')
    def set():
        # session['name'] = '湫兮如风'
        flash('湫兮', "name")
        flash('如风')
        return "SET..."
    
    # 只能取一次
    @app.route('/get')
    def get():
        name = get_flashed_messages(category_filter=["name"])
        print(name)
        return "GET..."
    
    if __name__ == '__main__':
        app.run()
    

    中间件

    from flask import Flask
    
    app = Flask(__name__)
    
    if __name__ == '__main__':
        app.run()
    
    app.run() 执行的是 run_simple(host, port, self, **options)
    run_simple 执行 self()
    self 是 app
    执行 self() 就是执行 app(),就是在执行 app 的 __call__ 方法,也就是 Flask 类里面的 __call__
    
    def __call__(self, environ, start_response):
        """The WSGI server calls the Flask application object as the
        WSGI application. This calls :meth:`wsgi_app` which can be
        wrapped to applying middleware."""
        return self.wsgi_app(environ, start_response)
    

    environ 是请求来的所有最原生的数据,start_response 是封装响应对象的。flask 的任何请求都从这里开始,想添加中间件,都从这里的 return 之前或之后进行添加。

    当然,不可能直接在源码中进行修改,可以自己重写

    from flask import Flask
    
    app = Flask(__name__)
    
    class Middleware(object):
        def __init__(self, old):
            self.old = old
    
        def __call__(self, *args, **kwargs):
            # 旧的 wsgi_app()
            return self.old(*args, **kwargs)
    
    app.wsgi_app = Middleware(app.wsgi_app)
    
    if __name__ == '__main__':
        app.run()
    
        # app.run() 就是在执行 app.__call__,返回 return self.wsgi_app()
        # 这里的 self 就是 app 自己,所以 self.wsgi_app 就是上面写的 app.wsgi_app
        # 上面写的 app.wsgi_app 是 Middleware()
        # 所以这里 self.wsgi_app() 就是 Middleware()()
        # 会走它的 __call__ 方法,返回 return self.old(*args, **kwargs)
        # 这里的 self 是传过去的 app.wsgi_app,是去源码中查找 wsgi_app 并执行
    

    引入一个装饰器的知识点

    import functools
    
    def auth(func):
        @functools.wraps(func)
        def inner(*args, **kwargs):
            ret = func(*args, **kwargs)
            return ret
        return inner
    
    @auth
    def my_func():
        return "my func"
    
    @auth
    def my_tools():
        return "my tools"
    
    print(my_func.__name__)		# my_func
    print(my_tools.__name__)	# my_tools
    

    针对于前面的登录 Demo,就可以使用装饰器而不必在每个功能下面都加上 session 的判断了

    但是当接口多了起来,在每个接口下都加上 @auth 也不太现实,所以可以放在中间件里。

    有一个装饰器叫做 @app.before_request,它的作用是任何视图函数的请求进来都要先执行这个装饰器函数,这就和 Django 中间件里的 process_request 类似,如果有返回值,直接返回给用户,如果没有返回值,才执行下面的视图函数。

    @app.before_request
    def authentication():
        if request.path == "/login":
            return None
        if session.get('user_info'):
            return None
        return redirect('/login')
    

  • 相关阅读:
    JSP Web第五章整理复习 JSP访问数据库
    JSP Web第四章整理复习 JSP技术基础
    JSP Web第三章整理复习 开发环境搭建
    在n个球中,任意取出m个(不放回),求共有多少种取法
    递归比较字符串是否相等
    数组求和的3种常见递归方法
    打印begin~end
    jQuery简单实现图片预加载
    HTML5语义化标签重构页面
    jQuery插件slick实现响应式移动端幻灯片图片切换特效—大全
  • 原文地址:https://www.cnblogs.com/qiuxirufeng/p/12094538.html
Copyright © 2020-2023  润新知