美文网首页
2.8.6Flask --2 Flask路由,请求与响应,重定向

2.8.6Flask --2 Flask路由,请求与响应,重定向

作者: 寒暄_HX | 来源:发表于2020-03-06 16:02 被阅读0次

    Flask目录:https://www.jianshu.com/p/9b5e30320849

    路由

    路由充当了一个指路牌的作用,让用户访问想要访问的页面得到想要的数据。


    路由

    当然也可以多个页面指向同一个路由(不过这样肯定是有关联的页面,最好使用正则URL)

    路由配置

    Flask的路由配置是没有专门的文件存放的,基本是以装饰器的形式存在视图函数顶部。
    实例:

    from flask import Flask
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    #路由装饰器,语法为 app.route(url_name,methods)  
    #url_name:路由名
    #methods:请求方式,默认get请求,可以使用列表指定多种方式。例:['GET','POST']
    @app.route('/index')
    def hi_flask():
        return 'Hi,Flask'
    
    if __name__ == '__main__':
        app.run()
    
    页面截图

    同时,路由也有多种写法:

    参数传递:@app.route('/users/<username>')
    指定类型:@app.route('/users/<int:pwd>')


    参数类型表

    一个简单的传参请求

    实例:

    from flask import Flask,url_for
    app = Flask(__name__)
    
    #使用参数接受url
    @app.route('/user/<username>')
    #给username设置一个默认值,这样不输入username也可以访问到这个页面。
    def users(username=''):
        return "用户名:{}".format(username)
    
    if __name__ == '__main__':
        app.run()
    
    页面截图

    同时还有另外一种方式,就是API方式。
    实例:

    from flask import Flask
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    def hi_flask2():
        return 'Hi,Flask2'
    app.add_url_rule("/index2/", view_func=hi_flask2)
    #API函数,第一个参数是路由名,第二个参数要以关键字参数传入,值是一个配套的函数名。
    if __name__ == '__main__':
        app.run()
    
    页面截图

    这两种方式的详解

    首先我们从装饰器入手:

    源码如下
    -------
        def route(self, rule, **options):
            """A decorator that is used to register a view function for a
            given URL rule.  This does the same thing as :meth:`add_url_rule`
            but is intended for decorator usage::
    
                @app.route('/')
                def index():
                    return 'Hello World'
    
            For more information refer to :ref:`url-route-registrations`.
    
            :param rule: the URL rule as string
            :param endpoint: the endpoint for the registered URL rule.  Flask
                             itself assumes the name of the view function as
                             endpoint
            :param options: the options to be forwarded to the underlying
                            :class:`~werkzeug.routing.Rule` object.  A change
                            to Werkzeug is handling of method options.  methods
                            is a list of methods this rule should be limited
                            to (``GET``, ``POST`` etc.).  By default a rule
                            just listens for ``GET`` (and implicitly ``HEAD``).
                            Starting with Flask 0.6, ``OPTIONS`` is implicitly
                            added and handled by the standard request handling.
            """
    
            def decorator(f):
                endpoint = options.pop("endpoint", None)
                self.add_url_rule(rule, endpoint, f, **options)  
                #这里调用了add_url_rule
                return f
    
            return decorator
    也就是说,route只不过是封装了一下的装饰器,干活的还是add_url_rule。
    这样的话,大家直接用装饰器就好了。
    

    路由反向解析

    说到路由,就不能不能不说路由的反向解析,他可以帮助我们获得用户请求的路由与配套的视图函数。
    实例:

    from flask import Flask,url_for
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    #路由装饰器, 语法为 app.route(url_name,method)  前者是路由名, 后者是请求方式,默认get请求
    @app.route('/index')
    def hi_flask():
        return 'Hi,Flask'
    
    def hi_flask2():
        return 'Hi,Flask2'
    
    app.add_url_rule("/index2/", view_func=hi_flask2)
    #API函数,第一个参数是路由名,第二个参数要以关键字参数传入,值是一个配套的函数名。
    
    # 查看URL规则
    print(app.url_map)
    
    # 反向解析,通过视图名找到对应的路由
    with app.test_request_context():
        print(url_for('hello_world'))
        print(url_for('hi_flask2'))
    
    if __name__ == '__main__':
        app.run()
    输出结果:
    --------
    Map([<Rule '/index2/' (GET, OPTIONS, HEAD) -> hi_flas2k>,
     <Rule '/index' (GET, OPTIONS, HEAD) -> hi_flask>,
     <Rule '/' (GET, OPTIONS, HEAD) -> hello_world>,
     <Rule '/static/<filename>' (GET, OPTIONS, HEAD) -> static>])
    /
    /index2/
    

    当然 url_for()还有很多其他的功能,以后会慢慢说。

    请求与响应

    上下文

    上下文分为,请求上下文与应用上下文。用语文中的概念来理解即可。在计算机中,可以把它理解为环境。

    引用上下文

    current_app:当前应用的案例
    g:处理请求时的临时存储对象,每次请求都会重设这个对象

    请求上下文

    request:请求对象,封装了客户端发给服务端的HTTP请求
    session:用户会话,在各个会话中共享数据

    请求

    请求分派

    请求分派

    我们来了一个请求'/index/',那么这个请求该去找哪个url规则呢,这个让请求找到他目的地的过程就是请求分派。

    请求报文常用参数

    method:请求的方式(get,post等等)
    args:get请求提交的数据
    form:form表单提交的数据
    files:文件上传
    cookies:cookie的传输
    headers:HTTP请求头

    GET请求

    from flask import Flask,request
    app = Flask(__name__)
    
    @app.route('/user')
    def users():
        #request是获取用户请求对象,args是获取用户get请求数据 数据是dict类型。
        get_dict = request.args
        print(get_dict)
        #从数据集中获取某一个值。
        username = request.args.get('username')
        print(username)
        #既然是dict类型,还是get方法,肯定能设置默认值啦。
        page = request.args.get('page',1)
        print(page)
        return "用户名:{}".format(username)
    
    if __name__ == '__main__':
        app.run()
    ----------
    输出结果:
    ImmutableMultiDict([('username', 'lisi')])
    lisi
    1
    
    image.png

    POST请求

    在将模板操作时一起说。

    请求头

    headers是一个字典类型的数据,获取后还可以通过get函数得到我们想要的数据,例如请求的ip,系统平台等等。

    from flask import Flask,request
    app = Flask(__name__)
    
    @app.route('/user')
    def users():
        headers = request.headers
        return "请求头:{}".format(headers)
    
    if __name__ == '__main__':
        app.run()
    
    请求头

    请求钩子

    请求钩子就是用来校验用户请求舒服是否合法。有四个常用函数

    • before_first_request
      服务器初始化后第一个请求到达前执行
    • before_request
      每一个请求到达前执行
    • after_request
      每次请求处理完成后执行,如果请求过程中产生了日常,则不执行。
    • teardown_request
      每次请求处理完成后执行,如果请求过程中发生了异常也执行。
      实例1:
    from flask import Flask,request
    app = Flask(__name__)
    
    @app.before_first_request
    def first_req():
        print('first_request')
        print('------')
    
    @app.before_request
    def before_req():
        print('brfore_request')
        print('------')
    
    
    @app.route('/user')
    def users():
        get_dict = request.args
        print(get_dict)
        print('------')
        return "请求参数:{}".format(get_dict)
    
    if __name__ == '__main__':
        app.run()
    
    请求前

    before_first_request函数确实只在确认连接的时候认证一次,而before_request会对每一次连接进行认证。

    实例2:

    from flask import Flask,request
    app = Flask(__name__)
    
    @app.before_first_request
    def first_req():
        print('first_request')
        print('------')
    
    @app.before_request
    def before_req():
        print('brfore_request')
        print('------')
    
    @app.after_request
    def after_req(resp):
        print('after_request')
        print('------')
        return resp
    
    @app.route('/user')
    def users():
        get_dict = request.args
        print(get_dict)
        print('------')
        return "请求参数:{}".format(get_dict)
    
    if __name__ == '__main__':
        app.run()
    
    输出结果

    只要请求内部不报错, after_request就会完美执行。

    teardown_request可以作为一个异常处理的方法,我们这里不探究他的使用。

    响应

    我们处理完用户的请求,反馈给用户的数据就是响应。响应可以是各种数据。其中特殊的包括我们反馈的数据,页面,状态码和响应头。


    404

    我们请求一个不存在的页面,肯定会得到404的状态码。但是我们不想返回这个朴素的页面,这就需要我们的响应定制了。

    from flask import Flask,request
    app = Flask(__name__)
    
    @app.errorhandler(404)
    def not_fount(err):
        print(err)
        return '你要找的页面找不到了'
    
    if __name__ == '__main__':
        app.run()
    
    自定义404

    同时我们也可以修改一下返回的数据,例如状态码或者headers。

    @app.errorhandler(404)
    def not_fount(err):
        print(err)
        return '你要找的页面找不到了',404,{
            'is_login':False
        }
    
    自定义404

    接着来看响应经常用到的方法:

    make_response():相当于Django中的HttpResponse。
    from flask import Flask,make_response
    app = Flask(__name__)
    
    @app.route('/test')
    def test():
        make = make_response("<h1>这是一个测试页面</h1>",200)
        return make
    
    if __name__ == '__main__':
        app.run()
    
    make_response

    但是一般我们都是返回一个页面的:

    from flask import Flask,make_response,render_template
    app = Flask(__name__)
    
    @app.route('/test')
    def test():
        tmp = render_template('index.html')
        make = make_response(tmp,200)
        return make
    
    if __name__ == '__main__':
        app.run()
    
    render_template

    make_response 想要返回页面,不能直接写做:make_response('hello.html'),必须用render_template('hello.html')形式。

    重定向

    redirect():相当于 Django中的HttpResponseRedirect。
    from flask import Flask,make_response
    app = Flask(__name__)
    
    @app.route('/test')
    def test():
        make = make_response("<h1>这是一个测试页面</h1>",200)
        return make
    
    @app.route('/test1')
    def test1():
        return redirect('/test')
    
    if __name__ == '__main__':
        app.run()
    
    redirect

    同时还有一个中止重定向的函数:
    abort()函数用于提前退出一个请求,并用指定的错误码返回。

    from flask import Flask,make_response
    app = Flask(__name__)
    
    @app.route('/test')
    def test():
        make = make_response("<h1>这是一个测试页面</h1>",200)
        return make
    
    @app.route('/test1')
    def test1():
        headers = request.headers
        ip = headers.get('host')
        print(ip)
        ip_list = ['127.0.0.1:5000']
        if ip in ip_list:
            abort(403)
        return redirect('/test')
    
    if __name__ == '__main__':
        app.run()
    

    我们这里模仿了一个ip请求黑白名单的访问。如果请求ip是我们的黑名单ip,就抛出一个403请求中断当前请求。


    abort

    相关文章

      网友评论

          本文标题:2.8.6Flask --2 Flask路由,请求与响应,重定向

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