This theme is built with awescnb.|

session原理,闪现,请求扩展,中间件,蓝图

session的原理

flask的session源码分析

# 通过app.session_interface()----->可以找到SecureCookieSessionTnterface()类的对象
-open_session:请求来了,从cookie中取出字符串,把字符串反序列化成session对象
 def open_session(
        self, app: "Flask", request: "Request"
    ) -> t.Optional[SecureCookieSession]:
        s = self.get_signing_serializer(app)
        if s is None:
            return None
        val = request.cookies.get(self.get_cookie_name(app))
        if not val:
            return self.session_class()
        max_age = int(app.permanent_session_lifetime.total_seconds())
        try:
            data = s.loads(val, max_age=max_age)
            return self.session_class(data)
        except BadSignature:
            return self.session_class()

-save_session:请求走时,把session对象,序列化成字符串,放到cookie中

    def save_session(
        self, app: "Flask", session: SessionMixin, response: "Response"
    ) -> None:
        name = self.get_cookie_name(app)
        domain = self.get_cookie_domain(app)
        path = self.get_cookie_path(app)
        secure = self.get_cookie_secure(app)
        samesite = self.get_cookie_samesite(app)
        httponly = self.get_cookie_httponly(app)
        if not session:
            if session.modified:
                response.delete_cookie(
                    name,
                    domain=domain,
                    path=path,
                    secure=secure,
                    samesite=samesite,
                    httponly=httponly,
                )
            return
        # Add a "Vary: Cookie" header if the session was accessed at all.
        if session.accessed:
            response.vary.add("Cookie")
        if not self.should_set_cookie(app, session):
            return
        expires = self.get_expiration_time(app, session)
        val = self.get_signing_serializer(app).dumps(dict(session))  # type: ignore
        response.set_cookie(
            name,
            val,  # type: ignore
            expires=expires,
            httponly=httponly,
            domain=domain,
            path=path,
            secure=secure,
            samesite=samesite,
        )

闪现

主要作用:假设在a页面操作出错,跳转到b页面,在b页面显示a页面的错误信息
		-本质其实就是在a页面,把错误信息放到了某个位置,在b页面把错误取出来
    
放值:
	 flash(message='信息错误')
     分类: flash(message='信息错误',category='error')
        
取值:get_flashed_messages()
	 按分类取值: get_flashed_messages(category_filter=['error'])
    
    
    
'''
	等同于djagno的message框架
'''

请求扩展

before_request

作用:类比django中间件的peocess_request,在请求到来执行路由函数之前先执行,但是如果有多个,顺序是从上往下执行

应用:基于它做用户登录认证

'''
注意:如果before_request的返回值不是None的情况下,返回的而是别的值,那么后续的请求都不会执行,本次请求直接返回,如果定义了after_request那么会接着它执行, 最终本次请求响应结束。
'''

@app.before_request
def process_request(*args,**kwargs):
    if request.path == '/login':
        return None
    user = session.get('user_info')
    if user:
        return None
    return redirect('/login') 

after_request

作用: 类比django中间件中的process_response,如果请求没有出现异常的情况下, 会在请求返回return之前执行. 但是如果有多个顺序是从下往上执行.

@app.after_request  # 后执行
def process_response1(response):
    print('process_response1 走了')
    return response

@app.after_request  # 先执行
def process_response2(response):
    print('process_response2 走了')
    return response

before_first_request

作用:项目启动起来接收到第一次请求时执行

应用:项目初始化用来保证以后项目只要不重启就不再继续执行

@app.before_first_request
def first():
    print('我的第一次')

teardown_request

作用: 在每一个路由函数执行完毕之后执行,即使遇到了异常也会执行. (提示: 返回reutrn没有任何的效果, 不能控制返回的结果)

应用: 记录日志

@app.teardown_request  
def ter(e):  # e就是上一个路由函授执行过程中出现被捕获的异常信息.
    print(e)
    print('我是teardown_request ')

errorhandler

作用: 绑定错误的状态码进而可以捕获服务器的错误, 并返回对应的错误页面.

@app.errorhandler(500)
def error_500(arg):
    return render_template('error.html', message='500错误')


@app.errorhandler(404)
def error_404(arg):
    return render_template('error.html', message='404错误')

'''
	arg: 错误信息
'''

template_global------全局的标签

作用: 全局的标签, 在任意的html页面中就可以直接使用, 不需要在render_template中传递参数以后才能使用.

@app.template_global()
def sb(a1, a2):
    return a1 + a2

# html页面中直接使用, 不需要传递参数.
{{ sb(1,2) }}

template_filter-----过滤器

@app.template_filter()
def db(a1, a2, a3):
    return a1 + a2 + a3

# html页面中直接使用, 不需要传递参数. 其中1传递给a1, 2传递给a2, 3传递给a3. (提示: Django中的过滤器最多只可以传递二个参数)
{{ 1|db(2,3) }}

总结:

1.重点掌握before_request和after_request

2.注意有多个的情况,执行顺序

3.before_request请求拦截后(也就是return了值或者Response对象(jsonify,render_template,redirect))

中间件

class Md(object):
    def __init__(self, old_wsgi_app):
        self.old_wsgi_app = old_wsgi_app

    def __call__(self, environ, start_response):
        print('开始之前')
        ret = self.old_wsgi_app(environ, start_response)
        print('结束之后')
        return ret


if __name__ == '__main__':
    # 1. 我们发现当执行app.run方法的时候,最终执行run_simple,最后执行app(),也就是在执行app.__call__方法
    # 2. 在__call__里面,执行的是self.wsgi_app().那我们希望在执行他本身的wsgi之前做点事情。
    # 3. 所以我们先用Md类中__init__,保存之前的wsgi,然后我们用将app.wsgi转化成Md的对象。
    # 4. 那执行新的的app.wsgi_app,就是执行Md的__call__方法。
    # 5. 最后把原来的wsgi_app替换为自定义的

    app.wsgi_app = Md(app.wsgi_app)
    app.run()

蓝图

    由于项目开发是一个非常耗时间和精力的工程,如果我们将所有的Flask请求方法都写在同一个文件下的话,非常不便于我们代码管理和后期功能代码的添加。
    如下示例:我们在一个文件中写入多个路由,这会使代码维护变得困难。
如图所示,如果我们将所有的请求方法写在同一个处理文件下面的话,会导致我们的代码显得很没有逻辑性,如果我们后期想要修改代码或者添加新功能的话,就会显得很突兀,不知道如何下手,此时就需要我们提到的蓝图来解决这个问题,如果学过django可能了解过django中的app,django中app的主要作用就是将django项目分成一个个单独的app模块,然后将所有app分配不同的处理功能,通过路由分配将它们连接成一个大django项目,其实Flask中的蓝图和django中的app功能大同小异,下面我们大概的了解一下Flask的蓝图,代码如下

   我们首先创建一个主的路由配置文件manage.py,该文件主要的作用就是启动整个的Flask框架(项目),如图所示
 接着,我们在manage.py的平级目录下创建两个文件admin.py 、user.py,我们大概看一下两个文件的内容
 这两个文件相当于django中两个app,不同是django中路由分配是将总路由通过include分配给app的urls.py路由文件,而Flask是通过蓝图注册方式将蓝图添加到主app中,user.py,admin.py主要是创建蓝图,然后为创建的蓝图添加路由配置,接着我们就可以在主路由文件manage.py中将我们创建的蓝图注册到主app中。
这样配置好以后就可以实现路由分层管理,我们来试一下,运行主程序manage.py
在浏览器中访问所设置的路由

补充

蓝图还能实现类似django中的路由分发功能,或者叫路由前缀

user.py:
    from flask import Blueprint
    user = Blueprint('user', __name__, url_prefix='/user/')
    '''
    	url_prefix:路由前缀
    '''
    @user.route('/user/hello')
    def hello():
        return '/user/hello'
    
    
'''
原来的路由为 http://127.0.0.1:5000/user/hello

现在的路由为 http://127.0.0.1:5000/user/user/hello

在原有路由前加了前缀
'''

本文作者:春游去动物园

本文链接:https://www.cnblogs.com/chunyouqudongwuyuan/p/16566349.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   春游去动物园  阅读(34)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开
  1. 1 生分 川青
生分 - 川青
00:00 / 00:00
An audio error has occurred.

生分 - 川青

词:莎子

曲:邵翼天

编曲:林亦

混音:罗杨轩

吉他:林亦

制作人:谢宇伦

监制:曾炜超/陈显

策划:+7

统筹:黄染染

出品:漫吞吞文化

『酷狗音乐人 • 星曜计划』

全方位推广,见证星力量!

「版权所有未经许可 不得商业翻唱或使用」

我们怎么变得那么生分

用了几年也没解开疑问

有些事你不提我也不问

在陌生与熟悉间找平衡

有些话一开口会伤人

有些话一开口会伤人

所以我选择默不作声

所以我选择默不作声

爱一个人

若甘愿陪衬

甘愿牺牲

也许换个名分

也不是没可能

我不怕在爱里做个蠢人

我不怕在爱里做个蠢人

也不怕爱过之后再分

也不怕爱过之后再分

爱一个人

有万种身份

万种可能

只是没想到

我们最后友人相称

我们怎么变得那么生分

我们怎么变得那么生分

连说话都要掌握好分寸

怕不注意流言

见缝插针

怕不小心我们

成陌生人

我们怎么变得那么生分

用了几年也没解开疑问

有些事你不提我也不问

在陌生与熟悉间找平衡

有些话一开口会伤人

有些话一开口会伤人

所以我选择默不作声

所以我选择默不作声

爱一个人

若甘愿陪衬

甘愿牺牲

也许换个名分

也不是没可能

我不怕在爱里做个蠢人

我不怕在爱里做个蠢人

也不怕爱过之后再分

也不怕爱过之后再分

爱一个人

有万种身份

万种可能

只是没想到我们最后

友人相称

我们怎么变得那么生分

连说话都要掌握好分寸

怕不注意流言见缝插针

怕不小心我们成陌生人

我们怎么变得那么生分

用了几年也没解开疑问

有些事你不提我也不问

在陌生与熟悉间找平衡

我们怎么变得那么生分

我们怎么变得那么生分

连说话都要掌握好分寸

怕不注意流言见缝插针

怕不小心我们成陌生人

我们怎么变得那么生分

用了几年也没解开疑问

有些事你不提我也不问

在陌生与熟悉间找平衡