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

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/')
指定类型:@app.route('/users/')


参数类型表

一个简单的传参请求

实例:

from flask import Flask,url_for
app = Flask(__name__)

#使用参数接受url
@app.route('/user/')
#给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([ hi_flas2k>,
  hi_flask>,
  hello_world>,
 ' (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("

这是一个测试页面

",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("

这是一个测试页面

",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("

这是一个测试页面

",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路由,请求与响应,重定向)