flask框架之蓝图、蓝图钩子

前言

这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题

于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。

微信小程序搜索:Python面试宝典

或可关注原创个人博客:https://lienze.tech

也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习

蓝图

随着flask程序越来越复杂,我们需要对项目进行模块化的处理,那么就可以通过蓝图BluePrint

Blueprint具有如下属性

  1. 一个项目可以具有多个Blueprint,一个Blueprint可以理解是一个应用
  2. 可以将一个Blueprint注册到任何一个未使用的URL下比如 “/”、“/sample”或者子域名,相当于路由分发
  3. Blueprint可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的
  4. 在一个应用初始化时,就应该要注册需要使用的Blueprint,提前规划项目结构

使用蓝图

创建一个python的包目录,这个目录代表一个app,我们叫做user,在蓝图目录下新建views.py

views.py中创建蓝图对象user_blueprint

# user/views.py.py
from flask import Blueprint

user_blueprint = Blueprint('user', __name__, url_prefix="/user")

关于Blueprint对象,他的参数如下

class Blueprint:
  	...
    def __init__(self,
          name, import_name,
          static_folder=None,
          static_url_path=None,
          template_folder=None,
          url_prefix=None,
  	...
  • name

    路由分发命名,比如一个endpoint值为index的函数在当前蓝图下,那么url_for("user.index")可以访问到他

  • import_name

    制定了该蓝图所在的模块名,为当前文件

  • static_folder

    蓝图的静态资源目录

  • template_folder

    蓝图的模版资源目录

  • url_prefix

    该蓝图下的视图路由前缀,注意使用前缀斜杠,否则会抛出异常urls must start with a leading slash

继续在views.py这个文件中编写flask的视图方法

# user/views.py
@user_blueprint.route("/", endpoint="index") # 使用蓝图对象进行路由映射
def index():
    return "index"

在主控制程序app下,注册这个user蓝图

# app.py
from flask import Flask
from user.views import user_blueprint # 导入蓝图应用下的蓝图对象

app = Flask(__name__)
app.register_blueprint(user_blueprint) # 注册到flask的app下

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

访问:http://127.0.0.1:5000/user/

就可以看到编写的视图效果

蓝图资源

蓝图有自己的目录,它的所有资源也可以都在其目录下,比如static,template目录,我们可以指定蓝图自己的模板目录和静态目录

比如我们创建蓝图时传入

user_blueprint = Blueprint('user', __name__,
                           url_prefix="/user",
                           template_folder='templates',
                           static_folder='static')

那么这个蓝图使用静态资源时,可以通过url_for动态寻找到当前蓝图目录下static中的静态资源

url_for("user.static", filename="test.css")

那么模版文件又是什么情况呢?

  1. 如果项目根下的templates目录中有相应的模版文件,直接使用
  2. 到定义蓝图的目录下查找制定的template_folder目录中的相应模版文件,相对当前蓝图文件所在目录

蓝图路由

类似django的路由反向解析,直接通过"name.endpoint"结合url_for方法即可,比如这里的index视图的路由解析方式

url_for("user.index")

传递参数还是老样子

url_for("user.index", id=1)

蓝图钩子

有些时候,除了全局对于flask-app的请求钩子控制,还可以使用针对于某些蓝图作用域的请求钩子

在具体的某个蓝图实例中,可以看到如下源码

def before_request(self, f):
    """Like :meth:`Flask.before_request` but for a blueprint.  This function
        is only executed before each request that is handled by a function of
        that blueprint.
    """
    self.record_once(
        lambda s: s.app.before_request_funcs.setdefault(self.name, []).append(f)
    )
    return f

当初始化了某个蓝图对象后,对这个蓝图内的路由进行请求钩子的控制,可以使用

from flask.blueprints import Blueprint
app_test = Blueprint("app_test", __name__)

app_test.before_request(lambda: print('只在当前蓝图请求生效'))
上一篇:Flask Response不支持gb2312编码


下一篇:记录搭建Ubuntu 20.04 LTS+Python3+Flask环境