flask学习笔记(3)——flask设置路由动态参数和重定向操作

flask设置路由动态参数和重定向操作

路由动态参数

  • 通过视图函数绑定的url路径来传递动态参数
    • 获取int类型动态参数,此时前端传入的动态参数必须是int类型
      @app.route("/param/<int:param>")
      def param_int(param):
          return f"<h1>传入的int类型参数是:{param},提示:传入其他类型参数会报错!</h1>"
      

      此时运行flask服务,前端访问http://127.0.0.1:5000/param/198 ,前端展示为传入的int类型参数是:198,提示:传入其他类型参数会报错!

    • 获取float类型动态参数,此时前端传入的动态参数必须是float类型
      @app.route("/param/<float:param>")
      def param_float(param):
          return f"<h1>传入的float类型参数是:{param},提示:传入其他类型参数会报错!</h1>"
      

      此时运行flask服务,前端访问http://127.0.0.1:5000/param/9.9 ,前端展示为传入的float类型参数是:9.9,提示:传入其他类型参数会报错!

    • 获取path路径类型动态参数**(动态参数可以包含'/')**,此时前端传入的动态参数必须是path类型
      @app.route("/param/<path:param>")
      def param_path(param):
          return f"<h1>传入的path类型参数是:{param},提示:传入其他类型参数会报错!</h1>"
      

      此时运行flask服务,前端访问http://127.0.0.1:5000/param/api/meta/translation ,前端展示为传入的path类型参数是:api/meta/translation,提示:传入其他类型参数会报错!

    • 获取string类型动态参数**(动态参数不可以包含'/')**,此时前端传入的动态参数必须是string类型
      @app.route("/param/<string:param>")
      def param_string(param):
          return f"<h1>传入的string类型参数是:{param},提示:传入其他类型参数会报错!</h1>"
      

      此时运行flask服务,前端访问http://127.0.0.1:5000/param/我叫小花花,今天21岁了 ,前端展示为传入的string类型参数是:我叫小花花,今天21岁了,提示:传入其他类型参数会报错!

  • 通过request来获取前端url路径使用?key1=value1&key2=value2的形式来获取传入的动态参数。
    @app.route("/hello")
    def say_hello():
        name = request.args.get('name')
        age = request.args.get('age')
        return "<h1>hello " + name + ",你的年龄是" + age + "。</h1>"
    

    此时运行flask服务,前端访问http://127.0.0.1:5000/hello?name=小花花&age=21 ,前端展示为hello 小花花,你的年龄是21。;访问http://127.0.0.1:5000/hello?name=熊大&age=10 ,前端展示为hello 熊大,你的年龄是10。

  • 补充知识:可以通过Python标准库uuid来生成一个唯一ID。每次生成的uuid都是唯一的。
    import uuid
    print(uuid.uuid4()) # 4b994059-b244-44c8-ba7a-4282bb504f78
    print(type(uuid.uuid4())) # <class 'uuid.UUID'>
    

flask路由自动重定向(了解即可,手动设置路由重定向才是重点)

flask的哲学:/index/和/index是两个不同的URLpath,不能搞混了。

代码举例说明/index/和/index是两个不同的URLpath

#!/usr/bin/python3
# @FileName    :flask_redirect.py
# @Time        :2020/6/1 下午11:47
# @Author      :ABC
# @Description :
from flask import Flask

app = Flask(__name__)


@app.route("/index")
def index():
    return "这是`/index`页面!"


if __name__ == '__main__':
    app.run(debug=True)

此时访问http://127.0.0.1:5000/index , 前端页面会展示这是index页面!

然后在访问http://127.0.0.1:5000/index/ ,前端页面会展示Not Found。The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

翻译过来说的就是:找不到。在服务器上找不到请求的URL。如果您手动输入网址,请检查拼写,然后重试。

这就说明了/index//index是两个不同的URLpath,体现了flask的严谨哲学(手动狗头~)

flask自动重定向示例

再看下边的代码

#!/usr/bin/python3
# @FileName    :flask_redirect.py
# @Time        :2020/6/1 下午11:47
# @Author      :ABC
# @Description :
from flask import Flask

app = Flask(__name__)


@app.route("/index/")
def index():
    return "这是index页面!"


if __name__ == '__main__':
    app.run(debug=True)

相比之前的代码,现在的index()视图函数绑定的路由的URLpath/index/比之前的index()视图函数绑定的路由的URLpath/index多了一个/斜杠。

此时我们再次访问http://127.0.0.1:5000/index ,发现前端依然展示这是index页面!,说明响应成功了。

然后我们使用F12打开浏览器抓个包看一下。
浏览器抓到两个index相关的请求包
我们可以看到一共抓到了两个index相关的请求包。

先看一下第一个/index的请求包的响应状态码(Status Code)响应头(Response Headers)信息
index的General信息
可以看到接口响应状态码为308,也就是永久重定向(PERMANENT REDIRECT)

然后接着看/index的响应体数据,发现没有任何数据。
index的响应体数据

然后再接着看/index/响应状态码(Status Code)200
index斜杠的请求头信息

/index/的响应体数据才是返回了我们定义的路由函数的返回值这是index页面!
index斜杠的响应数据

总结一下,当我们访问http://127.0.0.1:5000/index 时,而我们实际的视图函数index()中路由绑定的URLpath是/index/,但是flask程序最后依然通过308永久重定向将请求由/index重定向到/index/了,这就提现了flask的灵活且对用户友好的特点

最后再来看一下flask自动重定向请求的整个过程。

flask访问URLpath不带斜杠后永久重定向流程

路由注册机制

那么在flask中如何手动设置重定向呢,首先我们先来搞懂flask中的路由注册机制,顺便总结一下在flask中注册路由的相关知识。

flask中注册路由一共有2种方法

  1. 装饰器注册,也就是在视图函数上使用装饰器[@app.route("/index/")]来绑定路由,如:
    @app.route("/index/")
    def index():
        return "这是index页面!"
    
  2. 集中注册路由,通过app.add_url_rule()来集中注册路由,如:
    #!/usr/bin/python3
    # @FileName    :flask_redirect.py
    # @Time        :2020/6/1 下午11:47
    # @Author      :ABC
    # @Description :
    from flask import Flask
    
    app = Flask(__name__)
    
    
    # @app.route("/index")
    # def index1():
    #     return "这是index页面!"
    
    # @app.route("/index/")
    # def index():
    #     return "这是index页面!"
    
    
    def hello():
        return "hello"
    
    
    def say_name():
        return "我叫小花花!"
    
    
    app.add_url_rule('/hello', hello)
    # endpoint设置为`注册路由的地址`,也就是`URLpath`;view_func设置为视图函数名称,注意视图函数名称不能加`()`,只要函数名
    app.add_url_rule(endpoint='/name', view_func=say_name)
    
    if __name__ == '__main__':
        app.run(debug=True)
    

总结一下,使用装饰器注册路由主要适用于flask小型项目,使用app.add_url_rule(endpoint=XXX, view_func=XXX)集中注册路由主要适用于flask大型项目。

flask手动设置路由重定向

  1. 在装饰器中使用redirect_to=XXX如:@app.route(redirect_to='/')

    #!/usr/bin/python3
    # @FileName    :flask_manual_redirect.py
    # @Time        :2020/6/3 上午12:24
    # @Author      :ABC
    # @Description :
    from flask import Flask
    
    app = Flask(__name__)
    
    
    @app.route("/")
    def home():
        return "这是home首页!"
    
    
    print(app.url_map)
    
    
    @app.route("/login", methods=['GET'], endpoint='user_login', redirect_to='/')  # 在装饰器中设置重定向,程序运行时不会执行当前视图函数login() 
    def login():
        print('执行了login函数!')
        return "登录成功!"
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    启动flask服务,前端访问http://127.0.0.1:5000/login ,浏览器抓到的包如下

    抓到的第1个请求

    重定向1

    抓到的第2个请求

    重定向2

    可以看到请求已经从/login被重定向到/了。同时控制台也没有打印login()视图函数中的print('执行了login函数!')语句的内容说明了在装饰器中设置重定向,程序运行时不会执行当前视图函数login()

    重定向控制台未打印print语句的内容

  2. 通过在视图函数的return语句调用flask包中redirect()方法来设置路由重定向

    #!/usr/bin/python3
    # @FileName    :flask_manual_redirect.py
    # @Time        :2020/6/3 上午12:24
    # @Author      :ABC
    # @Description :
    from flask import Flask, redirect, url_for
    
    app = Flask(__name__)
    
    
    @app.route("/", endpoint='home')
    def home():
        return "这是home首页!"
    
    
    print(app.url_map)
    
    
    # 路由重定向方法1
    # @app.route("/login", methods=['GET'], endpoint='user_login', redirect_to='/')  # 在装饰器中设置重定向,程序运行时不会执行当前视图函数login()
    # def login():
    #     print('执行了login函数!')
    #     return "登录成功!"
    
    # 路由重定向方法2
    @app.route("/login", methods=['GET'], endpoint='user_login')
    def login():
        print('执行了login函数!')
        # endpoint代表视图函数和路由的绑定关系。
        # 使用url_for(endpoint=xxx)方法配合redirect()进行路由重定向操作。
        '''
        为什么要使用url_for(endpoint=xxx)方法?
        因为通常我们路由的地址会因为需求而经常改变,但是endpoint(视图函数和路由的绑定关系)是固定的,
        所以可以通过url_for(endpoint=xxx)方法再配合redirect()进行路由重定向操作。
        '''
        return redirect(url_for(endpoint='.home'))  # 需要从flask包中导入`redirect`方法
    
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    启动flask服务,前端访问http://127.0.0.1:5000/login ,浏览器抓到的包如下

    抓到的第1个请求

    重定向3

    抓到的第2个请求

    重定向4

    可以看到请求已经从/login被重定向到/了。同时控制台也打印了login()视图函数中的print('执行了login函数!')语句的内容说明了在视图函数的return语句调用flask包中redirect()方法来设置路由重定向,依然会执行当前视图函数login()的内容

    重定向控制台打印了print语句的内容

好了,今天的内容就到这里了。好累啊-.-