• flask框架-中


    路由扩展

    @app.route和app.add_url_rule参数

    # rule,URL 规则
    # view_func,视图含数名称
    # defaults = None,默认值,当url中无参数,函数需要参数时,使用defaus={"k","val"},
    # 来为其函数提供参数
    # endpoint = None,名称,用于反向解析生成URL 极url_for{“名称”}
    # method = None ,允许的请求方式,如:["GET","POST"]

    参数的使用:

    严格模式:strict_slashes=False  重定向:redirect_to = None,
    # app.add_url_rule("/", view_func=UserView.as_view(name="user"))
    # defaults = None, 默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'}
    # #对URL最后的 / 符号是否严格要求
    # strict_slashes = None
    #     '''
    #         @app.route('/index', strict_slashes=False)
            #访问http://www.xx.com/index/ 或http://www.xx.com/index均可
            # @app.route('/index', strict_slashes=True)
    #         #仅访问http://www.xx.com/index
    #     '''
    # #重定向到指定地址
    # redirect_to = None,
    
    
    from flask import Flask,views,render_template,redirect
    app=Flask(__name__)
    
    # strict_slashes,参数的说明:该参数是用来设置路由的匹配,设置严格模式,
    # False是非严格模式,True是严格模式,后缀的配置机制”/“
    
    # redirect_to="login" 是默认跳转的页面,重定向到..
    
    @app.route("/index",strict_slashes=True,redirect_to="/login")
    def index():
        return "ok"
    
    @app.route("/login")
    def login():
        return "helloworld"
    
    # 反向解析
    @app.route("/detail/<int:nid>")
    def detail(nid):
        print(nid)
        return "Good"
    
    if __name__ == '__main__':
        app.run()

      子域名访问:subdomain = None(了解)

    支持正则

     需要使用正则表达式来实现对URL和数据的操作,需要以下几个步骤。

    # 添加到flask中
    # 我们要用自定义的路由,用正则的话 #1导入from werkzeug.routing import BaseConverter # 2我先要写一个类,然后继承BaseConverter,然后实现__inti__, def to_python(self, value):to_url(self, value) # 3 app.url_map.converters['随便'] = RegexConverter 需要注册才会失效 #4 我们在路由里面@app.route('/index/<regex1("d+"):nid>'),regex1='随便,regex1("正则表达式") #5 regex1("正则表达式")匹配出来的结果,返回to_python,一定要return #6 当我们做反向解析的解析的时候,我们的参数,会传递给to_url,return的结果才是我们拼接到我们路由上

    代码演示

    from flask import Flask,views,url_for
    
    from werkzeug.routing import BaseConverter
    
    app = Flask(import_name=__name__)
    
    class RegexConverter(BaseConverter):
        """自定义url匹配正则表达式"""

    def __init__(self,map,regex): super(RegexConverter, self).__init__(map) self.regex = regex
    def to_python(self, value):

    """"路由匹配时,匹配成功后传递给视图函数中参数的值 """ # value就是正则匹配出来的结果 print("value",value,type(value)) return "Good"

    def to_url(self,value): """使用url_for反向解析,传递的参数经过该方法处理,返回的值用于生成URL中的参数""" val = super(RegexConverter,self).to_url(value) print(val) return val # 路由的传参及使用 app.url_map.converters['regex1'] = RegexConverter @app.route('/index/<regex1>("d+"):nid',endpoint="test") def index(nid): print("nid",nid,type(nid)) print(url_for("test",nid="help")) return "Index" if __name__ == '__main__': app.run()

    模板

    view.py

    Markup等价django的mark_safe,  extends,include一模一样

    from flask import Flask,render_template,request,redirect,session,url_for,Markup
    app = Flask(__name__)
    app.debug = True
    app.secret_key = 'sdfsdfsdfsdf'
    
    USERS = {
        1:{'name':'张三','age':18,'gender':'','text':"道路千万条"},
        2:{'name':'李四','age':28,'gender':'','text':"安全第一条"},
        3:{'name':'王五','age':18,'gender':'','text':"行车不规范"},
    }
    def func1(st,st1):
        return Markup(f"<h1>jsaon-gdx{st}{st1}</h1>")
    
    @app.route('/list',methods=['GET'])
    def list():
        info=USERS
    
        return render_template('list.html',info=info,html="<h1>jsaon-gdx</h1>",html1=func1)
    @app.route('/detail/<int:nid>',methods=['GET'],endpoint="good")
    def detail(nid):
    
        return "ok"
    
    if __name__ == '__main__':
        app.run()

    利用模板传给前端渲染,书写的格式

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {% for k,v in info.items() %}
            <tr>
                <td>{{k}}</td>
                <td>{{v.name}}</td>
                <td>{{v['name']}}</td>
                <td>{{v.get('name')}}</td>
                <td><a href="{{url_for('good',nid=k)}}">查看详细</a></td>
            </tr>
    {% endfor %}
    {{html
    |safe}} 过滤条件
    {{html1(
    "-DSB","-SB")}} </body> </html>

    绑定的模板实现的结果

    请求与响应

    from flask import Flask
    from flask import request
    from flask import render_template
    from flask import redirect
    from flask import make_response
    
    app = Flask(__name__)
    #请求里面有哪些内容
    #我们怎么定制响应
    
    @app.route('/login.html', methods=['GET', "POST"])
    def login():
        # 请求相关信息
        #提交的方法
        print(request.method)
        # request.args  get请求提及的数据
        print(request.args)
        # request.form   post请求提交的数据
        # request.values  post和get提交的数据总和
        # request.cookies  客户端所带的cookie
        # 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 #1导入make_response #2response=make_response(4剑客) #3 操作response # return response response=make_response(render_template('index.html')) response.set_cookie('jack', 'running') # response.delete_cookie('key') response.headers['X-Something'] = 'A value sbwewewe' return response if __name__ == '__main__': app.run()

    session

    cookie:存放在客户端的键值对
    session:存放在服户端的键值对
    token:存放在客户端,通过算法来校验

    在使用session之前必须先设置以下密钥

    app.secret_key = "dgsgjf" # 随意的字符串即可

    还需设置session对象,它允许你在不同请求间存储特定用户的信息

    session["username"] = "xxxx"

    删除session

    session.pop('username',None)

     如何获取和保存session

     可以配置全局的session

    源码分析:通过加密和解密获取键值对,存放在cookie,直接通过cookie获取。

    代码验证

    from flask import Flask,session
    
    app = Flask(__name__)
    app.secret_key="askjdaksd"
    app.config['SESSION_COOKIE_NAME']="dsb"

    # app.session_interface ''' app.session_interface这里面看 存session,
    1 调用save_session,将我们的session加密的val,读取配置文件['SESSION_COOKIE_NAME']得到key 2 将1种的key,val存储到cookies 取session 1 获取request里面的cookies,获取里面key,这个key就是['SESSION_COOKIE_NAME'],值就是加密的值 2 对该值进行解密
    ''' @app.route("/") def index(): session['jason']="gdx" return "ok" @app.route("/index1") def index1(): print(session['jason']) return "ok1" if __name__ == '__main__': app.run()

    查看cookie

    闪现:message

    '''
    什么是闪现?
    a 产生信息,传给 c 页面
    但是用户访问a页面以后,不是直接跳转到c,而是到b,或则是其他页面,但是用户访问c页面的时候,我希望把a给我的信息拿到。
    
    '''

    内部部分源码分析

     分析

    #1 如果要用flash就必须设置app.secret_key = 'asdfasdf'
    #2 只能取一次,在取就没有了
    #3 我们可以通过  flash('普通信息',category="info"),对信息做分类
    #4get_flashed_messages(with_categories=True,category_filter=("error",)),with_categories以键值对的形式获取
    #我们设置闪现,category_filter=("error",)进行分类信息的过滤.
    from flask import Flask,flash,get_flashed_messages,request
    
    app = Flask(__name__)
    app.secret_key = 'asdfasdf'
    
    @app.route('/index1')
    def index():
        #(category="message", message))
        flash('超时错误',category="error")
        flash('普通信息',category="info")
        return "ssdsdsdfsd"
        # return redirect('/error')
    
    @app.route('/error1')
    def error1():
        return "ok"
    
    @app.route('/error')
    def error():
        data = get_flashed_messages(with_categories=True,category_filter=("error","info"))
        data1 = get_flashed_messages(with_categories=True, category_filter=("error", "info"))
        print("data1",data1)
        print("data",data)
        return "错误信息"
    
    if __name__ == '__main__':
        app.ru

    总结

    存:flash,取:get_flashed_messages
    
    flash("",分类)
    
    get_flashed_messages(with_categories=False),category_filter=())
    
    如果什么都不传,直接拿出又有的flash存的值,而且没有分类名称
    
    with_categories=True:即拿值,有拿分类名称
    
    category_filter=("分类名称"),拿值得不是拿全部,是拿该“分类名称”的值
    
     特点:存了,你可以在任意一次请求中获取,但是一旦取了一次。就没有了,
         这里的一次,指的的请求一次

    请求扩展

    常见的有以下几种

    # @app.before_request
    # @app.after_request
    # @app.before_first_request
    # @app.teardown_request
    # @app.errorhandler(404)
    # @app.template_global()
    # @app.template_filter()

    源码入口

     常用请求方式的演练

    from flask import Flask,request,render_template
    
    app = Flask(__name__)
    
    # @app.before_request
    # def befor1():
    #     print(request)
    #     print("我是请求之前1")
    #     return "123"
    # @app.before_request
    # def befor2():
    #     print("我是请求之前2")
    
    #
    # @app.after_request
    # def after1(response):
    #     print("我是请求之后1")
    #     return response
    #
    # @app.after_request
    # def after2(response):
    #     print("我是请求之后2")
    #     return response
    
    # @app.before_first_request
    # def before_first():
    #     print("123")
    
    #如论有没有异常都会执行,如果没有异常这个参数就是None,有就记录这个异常
    # @app.teardown_request
    # def tear(e):
    #     print('teardown_request')
    #     print(e)
    
    #捕获异常,如果出现异常,而且状态就是@app.errorhandler(404),
    @app.errorhandler(404)
    def error_404(arg):
        print(arg)
        return "404错误了"
    
    # @app.errorhandler(500)
    # def error(arg):
    #     print(arg)
    #     return "500错误了"
    
    @app.template_global()
    def sb(a1, a2):
        return a1 + a2
    
    @app.template_filter()
    def db(a1, a2, a3):
        print(a1,a2,a3)
        return a1 + a2 + a3
    
    @app.route('/index')
    def index():
        print("我是真的视图")
        return render_template("index.html")
    
    
    if __name__ == '__main__':
        # app.__call__
        app.run()

    总结

    """
    
    1 @app.befor_request
        1.1 可以有多个,谁在前面谁先执行
        1.2 如果前面的有返回值,后面就不会执行,包括正真的视图函数,但是after_request依然会执行
    
    2 @app.after_request
        1.1可以有多个,谁在前面,谁后执行
        1.2 必须接受response,也必须返回response
    
    3 @app.before_first_request
        1.1 他是本项目启动后,获得第一个请求,才会走这里,其他的请求,就不走
    
    4  @app.teardown_request
        1.1 他是不管有没有错误都执行,如果没有错误,他接受的错误值None,
        1.2 虽然他能捕获错误,但是不能处理,只能记录
    
    5 @app.errorhandler(状态码)
    1.1 他是处理错误,但是你指定他处理哪一个状态码的错误
    1.2 如果发生对应状态码的错误,他就会触发,并处理,让用户无法感知
    1.3 如果没有对应的错误,将不会执行他
    
    6 @app.template_global()
    1.1 被该装饰器装饰的函数,我们可以在不用传递给模板的情况,模板可以直接调用。而且可以对于被装饰函数传值
    
    
    """

    中间件

    源码分析__call__切入:

     根据分析源码,自定义书写自定义中间件

    from flask import Flask
    
    app = Flask(__name__)
    
    class MyMiddleware:
        def __init__(self,wsgi_app):
            self.wsgi_app=wsgi_app
    
        def __call__(self,environ, start_response):
    
            print("之前")
            res=self.wsgi_app(environ, start_response)
            print("之后")
            return res
    @app.route(
    '/index') def index(): return "ok" if __name__ == '__main__': # app.__call__ app.wsgi_app = MyMiddleware(app.wsgi_app) app.run()

    请求流程:源码分析

  • 相关阅读:
    Java基础教程:Java内存区域
    Java基础教程:多线程基础——线程池
    微服务实践:服务治理
    微服务实践:服务设计
    微服务实践:什么是微服务
    SpringBoot学习笔记:读取配置文件
    Java进阶教程:使用Lombok提升开发效率
    Sagas模式
    执行力:Just Do It
    执行力:Just Do It
  • 原文地址:https://www.cnblogs.com/Gaimo/p/11843201.html
Copyright © 2020-2023  润新知