03-视图函数的路由

Flask程序运行过程

所有Flask程序必须有一个程序实例。

Flask调用视图函数后,会将视图函数的返回值作为响应的内容,返回给客户端。一般情况下,响应内容主要是字符串和状态码。

当客户端想要获取资源时,一般会通过浏览器发起HTTP请求。此时,Web服务器使用WSGI(Web Server Gateway Interface)协议,把来自客户端的所有请求都交给Flask程序实例。WSGI是为 Python 语言定义的Web服务器和Web应用程序之间的一种简单而通用的接口,它封装了接受HTTP请求、解析HTTP请求、发送HTTP,响应等等的这些底层的代码和操作,使开发者可以高效的编写Web应用。

程序实例使用Werkzeug来做路由分发(URL请求和视图函数之间的对应关系)。根据每个URL请求,找到具体的视图函数。 在Flask程序中,路由的实现一般是通过程序实例的route装饰器实现。route装饰器内部会调用add_url_route()方法实现路由注册。

调用视图函数,获取响应数据后,把数据传入HTML模板文件中,模板引擎负责渲染响应数据,然后由Flask返回响应数据给浏览器,最后浏览器处理返回的结果显示给客户端。

 示例:

# 导入Flask类
from flask import Flask

#Flask类接收一个参数__name__
app = Flask(__name__)

# 装饰器的作用是将路由映射到视图函数index
@app.route('/')
def index():
    return 'Hello World'

# Flask应用程序实例的run方法启动WEB服务器
if __name__ == '__main__':
    app.run()

视图函数的路由规则设置

 相同路由,不同视图函数(实现不同的请求方法)

# 通过methods限定访问方式
@app.route("/post_only", methods=["GET", "POST"])
def post_only():
    return "post only page"

@app.route("/hello", methods=["POST"])
def hello():
    return "hello 1"

@app.route("/hello", methods=["GET"])
def hello2():
    return "hello 2"

 同一视图函数多个路由(或装饰器后面的用到的@login_require)

@app.route("/hi1")
@app.route("/hi2")        
def hi():
    return "hi page"

 url_for 进行反解析进行反解析  redirect 重定向

from flask import Flask, current_app, redirect, url_for
...

@app.route("/index") def index(): """定义的视图函数""" return "hello flask" @app.route("/login") def login(): # url = "/" # 使用url_for的函数,通过视图函数的名字找到视图对应的url路径 url = url_for("index") return redirect(url) @app.route("/register") def register(): # url = "/" url = url_for("index") return redirect(url)

 url_map 函数     

if __name__ == '__main__':
    # 通过url_map可以查看整个flask中的路由信息
    print(app.url_map)
    # 启动flask程序
    app.run(debug=True)

路由提取参数与自定义路由转换器

默认转换器

# 127.0.0.1:5000/goods/123
# @app.route("/goods/<int:goods_id>")
@app.route("/goods/<goods_id>")  # 不加转换器类型, 默认是普通字符串规则(除了/的字符)
def goods_detail(goods_id):
    """定义的视图函数"""
    return "goods detail page %s" % goods_id

  

自定义转换器

# coding:utf-8

from flask import Flask, current_app, redirect, url_for
from werkzeug.routing import BaseConverter

app = Flask(__name__)

# 1.定义自己的转换器

# (1)
class MobileConverter(BaseConverter):
    def __init__(self, url_map):
        super(MobileConverter, self).__init__(url_map)
        self.regex = r'1[34578]\d{9}'

# (2)
class RegexConverter(BaseConverter):
    """正则转换器"""
    def __init__(self, url_map, regex):
        # 调用父类的初始化方法
        super(RegexConverter, self).__init__(url_map)
        # 将正则表达式的参数保存到对象的属性中,flask会去使用这个属性来进行路由的正则匹配
        self.regex = regex

    def to_python(self, value):
        """直接访问时被调用"""
        print("to_python方法被调用")
        # return "abc"
        # value是在路径进行正则表达式匹配的时候提取的参数
        return value

    def to_url(self, value):
        """使用url_for的方法的时候被调用"""
        print("to_url方法被调用")
        # return "15811111111"
        return value


# 2.将自定义的转换器添加到flask的应用中
app.url_map.converters["re"] = RegexConverter
app.url_map.converters["mobile"] = MobileConverter

# 127.0.0.1:5000/send/18612345678 # @app.route("/send/<mobile:mobile_num>") # MobileConverter @app.route("/send/<re(r'1[34578]\d{9}'):mobile_num>") def send_sms(mobile_num): return "send sms to %s" % mobile_num @app.route("/index") def index(): url = url_for("send_sms", mobile_num="18922222222") # /send/18922222222 return redirect(url) # 其他电话 @app.route("/call/<re(r''):tel>") def call_tel(tel): pass if __name__ == '__main__': # 通过url_map可以查看整个flask中的路由信息 print(app.url_map) # 启动flask程序 app.run(debug=True)

 路由参数会先经过转换器后再传给视图函数

 

Flask装饰器路由的实现:

Flask有两大核心:Werkzeug和Jinja2。Werkzeug实现路由、调试和Web服务器网关接口。Jinja2实现了模板。

Werkzeug是一个遵循WSGI协议的python函数库。其内部实现了很多Web框架底层的东西,比如request和response对象;与WSGI规范的兼容;支持Unicode;支持基本的会话管理和签名Cookie;集成URL请求路由等。

Werkzeug库的routing模块负责实现URL解析。不同的URL对应不同的视图函数,routing模块会对请求信息的URL进行解析,匹配到URL对应的视图函数,以此生成一个响应信息。

routing模块内部有Rule类(用来构造不同的URL模式的对象)、Map类(存储所有的URL规则)、MapAdapter类(负责具体URL匹配的工作);

posted @ 2019-01-16 23:21  元贞  阅读(350)  评论(0)    收藏  举报