Flask框架之路由与蓝图的使用

597 阅读8分钟

路由

概述

在Flask中,路由用于将HTTP请求与特定的Python函数相匹配。通过定义路由,Flask应用程序可以响应URL的请求,执行相应的函数,然后将结果返回给用户。

在Flask中,可以使用@app.route装饰器来创建路由。这个装饰器告诉Flask,当用户访问指定的URL时要执行装饰的函数

路由是一种映射关系,将一个URL地址与一个特定的处理函数绑定起来。在Flask中,可以使用装饰器@app.route(url) 来为某个URL指定对应的视图函数

路由的基本使用

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

查看路由信息

url_map对象

在Flask中,可以通过Flask实例对象app的url_map属性来获取应用程序中定义的所有路由信息。还可以使用url_map对象的方法和属性来查看每个路由所属的蓝图、请求方法和端点等详细信息。

from flask import Flask

app = Flask(__name__)

@app.route('/')
def route_map():
	print(app.url_map)
    return 'Hello, World!'
Map([<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
 <Rule '/' (HEAD, OPTIONS, GET) -> index>])
map:表示路由映射,容器列表

rule:路径规则,存储了url的路径名、http请求⽅法、端点(视图函数名)

可以遍历路由信息

for rule in app.url_map.iter_rules():
    print('name={} path={}'.format(rule.endpoint, rule.rule))
name=static path=/static/<path:filename>
name=index path=/

也可以通过视图返回路由信息

以json的方式返回应用内的所有路由信息

@app.route('/')
def route_map():
    """
    主视图,返回所有视图地址
    """
    rules_iterator = app.url_map.iter_rules()
    return json.dumps({rule.endpoint: rule.rule for rule in rules_iterator})

在这里插入图片描述

命令行方式

在Flask应用程序中,可以使用 flask 命令行工具来查看应用程序的路由信息。

flask routes

执行此命令将输出应用程序中所有定义的路由信息,包括路由规则、请求方法和端点等详细信息。

Endpoint Methods Rule
-------- ------- -----------------------
index GET /
static GET /static/<path:filename>
endpoint:端点,视图函数名的字符串形式

methods:请求⽅法

rule:路径规则

static是Flask框架帮助默认创建的静态路由,⽅便静态⽂件的访问

HTTP请求方法

在Flask中,可以使用路由装饰器提供的特定HTTP方法来指定请求方式(GET、POST、PUT等)。具体方法是,在路由装饰器中传递 methods 参数,并将所需的方法列在一个列表中。

利用methods参数可以自己指定一个接口的请求方式

from flask import Flask

app = Flask(__name__)

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


@app.route("/test2", methods=["GET", "POST"])
def test2():
    if request.method == 'POST':
        return 'Hello, POST!'
    else:
        return 'Hello, GET!'

注意:在Flask中,定义路由其默认的请求方式为:GET、OPTIONS(自带)、HEAD(自带)

蓝图

概述

在Flask中,蓝图是一种组织Flask程序路由的方式,它可以帮助我们更好地组织代码,使得应用程序更加模块化、易于管理。通过使用蓝图,我们可以将应用程序划分成多个模块,在每个模块内部定义自己的路由,然后将这些模块注册到主应用程序中。

在Flask中,使用蓝图Blueprint来分模块组织管理。蓝图实际可以理解为是一个存储一组视图方法的容器对象,但是一个Blueprint并不是一个完整的应用,它不能独立于应用运行,而必须要注册到某一个应用中。

蓝图特点:

一个应用程序可以具有多个蓝图Blueprint,可以将一个蓝图Blueprint注册到任何一个未使用的URL下,如:/user,在一个应用初始化时,就应该要注册需要使用的蓝图Blueprint

可以帮助开发者组织大型的应用程序。蓝图可以将应用程序划分为多个小块,每个小块负责处理自己的任务,从而使得代码更加易于维护和扩展。

具有独立的 URL 前缀和模板过滤器。通过在创建蓝图时指定 URL 前缀,可以将不同的蓝图映射到不同的 URL 上。同时,蓝图也可以定义自己的模板过滤器,在模板文件中使用。

可以与应用程序上下文分离。蓝图可以被注册到不同的应用程序对象上,并且可以根据需要进行激活和取消激活。这种分离可以方便地实现单元测试和集成测试。

可以与 Flask 扩展库集成。许多 Flask 扩展库都支持蓝图,例如 Flask-SQLAlchemyFlask-WTF 等。

支持钩子函数。通过定义视图函数之外的钩子函数,蓝图可以在请求处理的不同阶段执行一些操作,例如检查用户身份、记录日志等。

蓝图的基本使用

创建一个蓝图user_bp,并且定义了一个路由 /。在创建应用程序时,使用register_blueprint()方法将蓝图注册到应用程序中,此方法将蓝图中定义的所有路由规则添加到应用程序中。

from flask import Flask, Blueprint

# 创建Flask应用程序实例
app = Flask(__name__)

# 1.创建一个蓝图对象
user_bp = Blueprint('user', __name__)

# 2.在这个蓝图对象上进行:注册路由,指定静态文件夹,注册模版过滤器
@user_bp.route('/')
def user_info():
    return 'user_info'

# 3.在应用对象上注册这个蓝图对象
app.register_blueprint(user_bp)

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

蓝图的拆分

在Flask中,可以将蓝图的不同部分拆分到多个文件中,以提高代码组织性和可读性。因为蓝图(blueprint)可以像模块一样拥有多个文件,有助于将代码和逻辑结构化、分层次地组织,便于开发和维护,因此也称目录/包蓝图

1.创建mybp目录包,在的__init__.py文件中创建蓝图对象

from flask import Blueprint
# 1.创建蓝图对象
my_bp = Blueprint('my_bp ',__name__)

# 注意:一定要把使用蓝图对象的视图文件,导入到创建蓝图对象的文件中,且在创建蓝图对象的下面导入
from . import views

2.在mybp目录包下创建views.py文件

from . import my_bp

# 定义视图函数和路由
my_bp.route("/test")
def test():
    return 'OK'

3.在主应用程序中,使用register_blueprint方法将需要的每个蓝图注册到应用程序中

from mybp import my_bp
app = Flask(__name__)

# 注册my_bp蓝图对象
app.register_blueprint(my_bp)

也可以直接在视图views.py文件中,定义蓝图,并将路由定义添加到该蓝图中

from flask import Blueprint

bp = Blueprint('bp', __name__)

@bp.route('/')
def index():
    return 'Hello from bp!'

最后在主应用程序中导入注册

from flask import Flask
import views

app = Flask(__name__)
app.register_blueprint(views.bp)

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

指定蓝图的url前缀

可以在应用中注册蓝图时,通过指定url_prefix参数来设定路由的URL前缀。

创建一个名为bp的蓝图,并将其URL前缀设为/example。当访问http://localhost:5000/example/test时,会调用test()函数来处理该请求

from flask import Blueprint

bp = Blueprint('bp', __name__, url_prefix='/example')

@bp.route('/test')
def test():
    return 'test'

蓝图构造URL

在Flask 中,蓝图可以使用url_for() 函数构造URL。要在蓝图中使用url_for(),需要指定蓝图的名称和视图函数的名称。

基本使用:

在蓝图 bp 中定义了名为 hello_world 的视图函数,并在这个函数中使用 url_for() 构造另一个路由的URL,例如 /other

from flask import Blueprint, url_for

bp = Blueprint('bp', __name__)

@bp.route('/hello')
def hello_world():
    other_url = url_for('.other')
    return 'Hello World! Go to <a href="{}">{}</a>'.format(other_url, other_url)

@bp.route('/other')
def other():
    return 'This is the other page'

额外说明:

当想要从一个页面链接到另一个页面,可以使用 ​url_for()​ 函数,只是要在 URL 的末端加上蓝图的名称和一个点 ​.​作为前缀

url_for('user.index')

如果在一个蓝图的视图函数或是模板中想要从链接到同一蓝图下另一个端点, 可以通过对端点只加上一个点作为前缀来使用相对的重定向:

url_for('.index')

蓝图静态文件

在Flask中,蓝图对象创建时不会默认注册静态目录的路由,蓝图可以具有自己的静态文件目录,以便使用不同的静态文件作为主应用程序中的其他静态文件。要指定蓝图的静态文件目录,请使用 Blueprint 构造函数的static_folder参数

将蓝图所在目录下的static_user目录设置为静态目录

user = Blueprint("user",__name__,static_folder='static_user')

app.register_blueprint(user,url_prefix='/user')

然后使用/user/static_user/<filename>访问static_user目录下的静态文件。也可通过static_url_path改变访问路径

user = Blueprint("user",__name__,static_folder='static_user',static_url_path='/aaa')

app.register_blueprint(user,url_prefix='/user')

在 HTML 模板中引用蓝图的静态文件时,需要使用url_for() 函数和蓝图名称来生成正确的URL:

# url_for() 函数生成一个URL,其中 'user.static' 使用user蓝图的静态文件目录来查找文件 'style.css'
<link rel="stylesheet" href="{{ url_for('user.static', filename='style.css') }}">

注意:

指定的节点名称是 'static',它表示 Flask 用于提供静态文件的节点名称

如果蓝图的静态文件目录中包含与主应用程序的静态文件目录名称相同的文件,则将优先使用蓝图的静态文件。

蓝图模板目录

在Flask中,蓝图可以具有自己的模板目录,以便使用不同的模板文件作为主应用程序中的其他模板。

蓝图对象默认的模板目录为系统的模版目录,可以在创建蓝图对象时使用 template_folder 关键字参数设置模板目录

user = Blueprint('user',__name__,template_folder='my_templates')

使用 render_template() 函数呈现蓝图模板,该函数将使用user蓝图的模板目录中的hello.html文件来呈现模板。

from flask import render_template

@bp.route('/hello')
def hello_world():
    return render_template('hello.html')

注意:

 render_template() 函数呈现蓝图模板不需要指定模板目录的名称,因为Flask会自动查找与当前蓝图关联的目录

如果蓝图的模板目录中包含与主应用程序的模板目录名称相同的文件,则将优先使用蓝图的模板文件