• flask之请求与响应、闪现(阅后即焚)、请求扩展(before,after)、中间件、LOCAL对象、偏函数、


    1.flask请求与响应

    from flask import Flask,request,make_response,render_template
    
    app = Flask(__name__)
    
    
    
    
    @app.route('/login.html', methods=['GET', "POST"])
    def login():
        # 请求相关信息
        # request.method  提交的方法
        print(request.method)
        # request.args  get请求提及的数据
        print(request.args)
        # request.form   post请求提交的数据
        print(request.form)
        # request.values  post和get提交的数据总和
        print(request.values)
        # request.cookies  客户端所带的cookie
        print(request.cookies)
        # request.headers  请求头
        print(request.headers)
        # request.path     不带域名,请求路径
        print(request.path)
        # request.full_path  不带域名,带参数的请求路径
        # request.script_root
        # request.url           带域名带参数的请求路径
        # request.base_url      带域名请求路径
        # request.url_root      域名
        # request.host_url      域名
        # request.host          127.0.0.1:500
        # request.files
        # obj = request.files['the_file_name']
        # obj.save('/var/www/uploads/' + secure_filename(f.filename))
    
        # 响应相关信息
        # return "字符串"
        # return render_template('html模板路径',**{})
        # return redirect('/index.html')
        # return jsonify({'k1':'v1'})
    
        # 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
    
        #返回字符串
        #response = make_response("内容")
        #response.set_cookie("key","value")
    
        #返回html
        response=make_response(render_template("index.html"))
        response.headers['X-Something'] = 'sb'
        response.delete_cookie('jason')
        return response
    
    
    if __name__ == '__main__':
        app.run()
    
    

    2.闪现

    '''
    闪现解决的问题:-假设在a页面操作出错,c页面(操作了多少个页面,我不管),跳转到b页面,在b页面显示a页面的错误信息
    
    index页面出现错误,然后在error页面将错误信息抛出,这两个页面之间可以访问多个页面,只要有一次get_flashed_message,那么error就不能打印错误了
    
    '''
    
    from flask import Flask,flash,get_flashed_messages,request
    app = Flask(__name__)
    #闪现用到session,所以要加上secret_key,否则会报错
    app.secret_key = 'dfksdkf'
    
    
    @app.route('/index')
    def index():
        flash('超时错误')
        flash('价格有误', category='price')
        return '这是Index'
    
    @app.route('/error1')
    def error1():
        return 'ok'
    
    @app.route('/error')
    def error():
        """
        :return:
        """
        data = get_flashed_messages(with_categories=True,category_filter=('price',)) #展示分类名,筛选出分类名叫price的数据
        data2 = get_flashed_messages(with_categories=True) #把分类也取出来。
        data3 = get_flashed_messages() #分类默认是false
        print(data)
        print(data2)
        print(data3)
        #[('price', '价格有误')]
        # [('message', '超时错误'), ('price', '价格有误')]
        # ['超时错误', '价格有误']
        return '这是error'
    
    @app.route('/error2')
    def error2():
        # 再取一次就取不到了
        data = get_flashed_messages()
    
        print('error2', data)
    
        return '这是error2'
    
    if __name__ == '__main__':
        app.run()
    

    3.请求扩展

    from flask import Flask,request,render_template
    app = Flask(__name__)
    
    '''
    可以多个请求之前的函数
    执行顺序是谁在前面谁先执行
    如果前面的before_request有返回值,后面的都不会执行
    '''
    # @app.before_request
    # def sb():
    #     print(request)
    #     print("我是请求之前")
    #     return "我是请求之前1的返回"
    #
    # #上面有返回值,所以这里就不执行了
    # @app.before_request
    # def  sb1():
    #     print("我是请求之前2")
    #     #return "我是请求之前2的返回"
    
    #
    #
    # '''
    # 可以在请求之后添加多个after_request
    #
    # 执行顺序是谁在前面谁后执行(类似于django中间件的响应顺序,也可以理解为栈,后进先执行)
    # before_request对我的after_request没有影响,
    # 有没有返回值都会执行
    #
    #
    #
    #
    # '''
    # @app.after_request
    # def process_response1(response):
    #     print('process_response1 走了')
    #     return response
    #
    # @app.after_request
    # def process_response2(response):
    #     print('process_response2 走了')
    #     return response
    #
    #
    # #第一次请求之前打印,之后就不打印了
    # @app.before_first_request
    # def first():
    #    print("我的第一次")
    
    '''
    无论有没有异常都会执行,有异常会把异常传递进来
    
    '''
    
    @app.teardown_request
    def ter(e):
        print(e) #响应函数里面的a报错:name 'a' is not defined,会被捕捉出来
        print("我是异常")
    
    
    
    
    '''
    @app.errorhandler(要捕获的错误码)
    '''
    @app.errorhandler(500) # 服务器出错,就会传给前台 500错了,可以导一个render_template,渲染一个页面
    def error_404(arg):
        print(arg)
        return "500错误了"
    
    
    #html页面,不用传值就可以直接传过去
    @app.template_global()
    def sb(a1, a2):
        return a1 + a2
    
    
    @app.template_filter()
    def db(a1, a2, a3):
        return a1 + a2 + a3
    
    
    
    @app.route("/")
    def index():
        print("我是真的响应函数")
        # a
        return render_template("index.html")
    
    
    
    
    if __name__ == '__main__':
        # app.__call__()
        app.run()
    

    4.中间件

    '''
    中间件就是在请求来之前和请求走之后加一些东西
    在__call__中的self.wsgi_app之前和之后写,不改源码,直接抽出来重写
    '''
    
    from flask import Flask,flash,get_flashed_messages,request
    
    app = Flask(__name__)
    
    class MyMiddleware:
        def __init__(self,wsgi_app123):
            self.wsgi_app123=wsgi_app123
    
        def __call__(self, environ, start_response):
    
            print("123")
            res=self.wsgi_app123(environ, start_response)
            print("456")
            print(res)
            return res
    
    
    
    
    @app.route('/index')
    def index():
        # request.method
        # session['sd']
    
        return "ssdsdsdfsd"
    
    
    if __name__ == '__main__':
        #根据__call__里面的 wsgi_app注释部分,写如下模板的中间件,其中,类名(MyMiddleware是可以重命名的,但是与自己重写的类名要一致)
        app.wsgi_app = MyMiddleware(app.wsgi_app) #类加括号,执行__call__方法
        #app.run()本质就是执行app.__call__()
        # run函数里面的run_simple,然后需要传一个参数self对象,这样加括号,就执行了__call__方法
        # app.__call__()
        app.run()
    

    5.LOCAL对象

    # 不用local
    from threading import Thread
    import time
    cxw = -1
    def task(arg):
        global cxw
        cxw = arg
        time.sleep(2)
        print(cxw) #取出的全是9
    
    for i in range(10):
        t = Thread(target=task,args=(i,))
        t.start()
    
    #
    # flask中的request就是存在local对象中的,这样多线程请求的时候就不会乱掉了。
    #
    # 导入的local
    from threading import Thread
    from threading import local
    import time
    
    特殊的对象
    cxw = local()
    def task(arg):
        # 对象.val = 1/2/3/4/5
        cxw.value = arg
    
        time.sleep(2)
    
        print(cxw.value)#取出的是0-9,且每刷新一次就会重新赋值,不会出现重复数字
    for i in range(10):
        t = Thread(target=task,args=(i,))
        t.start()
    #
    # 字典的形式
    # 模拟上面Local对象中不会乱的线程的现象。
    
    from threading import get_ident,Thread
    import time
    storage = {}
    def set(k,v):
        ident = get_ident() #拿到当前线程的线程id
        if ident in storage: #在仓库中就改值,以最新的为准
            storage[ident][k] = v
        else:
            storage[ident] = {k:v} #不在仓库就加进去值
    def get(k):
        ident = get_ident()
        return storage[ident][k]
    
    
    def task(arg):
        set('val',arg)
        time.sleep(2)
        v = get('val')
        print(v)
    
    #在t = Thread 和 set('val', arg)两处打断点,可以看到,循环走完之后,才开始执行任务函数
    for i in range(10):
        t = Thread(target=task,args=(i,))
        print(i)
        t.start()
    
    # 面向对象的形式(就是把字典的形式封装成local类,这样使用时生成local对象)
    
    from threading import get_ident,Thread
    import time
    class Local(object):
        storage = {}
        def set(self, k, v):
            ident = get_ident()
            if ident in Local.storage:
                Local.storage[ident][k] = v
            else:
                Local.storage[ident] = {k: v}
    
        def get(self, k):
            ident = get_ident()
            return Local.storage[ident][k]
    #
    obj = Local()
    def task(arg):
    
        obj.set('val',arg)
        v = obj.get('val')
        print(v)
    for i in range(10):
        t = Thread(target=task,args=(i,))
        t.start()
    
    # 我们目的是推导出和上面local相同的用法,即对象.val这样,所以就想到.拦截,即__setattr__、__getattr__.
    # 下面的代码就是把上面面向对象中的set和get换成__setattr__和__getattr__
    
    
    from threading import get_ident,Thread
    import time
    class Local(object):
        storage = {}
        def __setattr__(self, k, v):
            ident = get_ident()
            if ident in Local.storage:
                Local.storage[ident][k] = v
            else:
                Local.storage[ident] = {k: v}
        def __getattr__(self, k):
            ident = get_ident()
            return Local.storage[ident][k]
    
    obj = Local()
    
    
    def task(arg):
        obj.val = arg
        time.sleep(1)
        print(obj.val)
    for i in range(10):
        t = Thread(target=task,args=(i,))
        t.start()
    
    每个对象都有自己的storage
    
    try:
        from greenlet import getcurrent as get_ident
    except Exception as e:
        from threading import get_ident
    from threading import Thread
    from threading import get_ident,Thread
    import time
    class Local(object):
        def __init__(self): #我们重写了__setattr__,所以这里写了self.storage后,就会调用自己的setattr,然后就调用getattr,一直递归,最后崩掉,故需要调用父类的__setattr__。
            object.__setattr__(self,'storage',{})
            #self.storage={}
        # storage={}
    
        def __setattr__(self, k, v):
            ident = get_ident()
            if ident in self.storage:
                self.storage[ident][k] = v
            else:
                self.storage[ident] = {k: v}
    
        def __getattr__(self, k):
            ident = get_ident()
            return self.storage[ident][k]
    
    obj = Local()
    obj1=Local()
    
    def task(arg):
        obj.val = arg
        obj.xxx = arg
        print(obj.val)
    for i in range(10):
        t = Thread(target=task,args=(i,))
    #     t.start()
    

    6.偏函数

    from functools import partial
    def test(a,b,c,d):
        return a+b+c+d
    
    tes=partial(test,a=1,b=2)
    
    print(tes(c=3,d=4))
    # print(tes(3,4))
    

    templates

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
    
    </head>
    <body>
    <h1> 我爱我的祖国</h1>
    {{sb(1,2)}} <!--直接使用函数-->
    {{12|db(1,1)}} <!--直接使用过滤器-->
    
    </body>
    </html>
    
  • 相关阅读:
    相对定位和绝对定位
    Html中常见的块级元素
    浮动的用法
    c#中质数判断
    函数
    asp.net Jquery+json 实现无刷新分页
    MS CRM2011 某个用户(团队)对某个实体的操作权限
    asp.net sitemap url动态参数
    MS CRM 2011 更改团队的业务部门
    MS CRM 2011 解决记录总数问题
  • 原文地址:https://www.cnblogs.com/michealjy/p/12050784.html
Copyright © 2020-2023  润新知