Flask中蓝图的使用方法详解

        在一个Flask 应用项目中,如果业务视图过多,可否将以某种方式划分出的业务单元单独维护,将每个单元用到的视图、静态文件、模板文件等独立分开?

        例如从业务角度上,可将整个应用划分为用户模块单元、商品模块单元、订单模块单元,如何分别开发这些不同单元,并最终整合到一个项目应用中。

1、蓝图介绍

1.1 蓝图介绍

在Flask中,使用蓝图Blueprint来分模块组织管理。【蓝图相当于Django中的子应用】

蓝图实际可以理解为是一个存储一组视图方法的容器对象,其具有如下特点:

  • 一个应用可以具有多个Blueprint
  • 可以将一个Blueprint注册到任何一个未使用的URL下比如 “/user”、“/goods”
  • Blueprint可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的
  • 在一个应用初始化时,就应该要注册需要使用的Blueprint

注意

但是一个Blueprint并不是一个完整的应用,它不能独立于应用运行,而必须要注册到某一个应用中。

1.2 蓝图简单使用方式

使用蓝图可以分为三个步骤

1. 创建一个蓝图对象【user是蓝图的名字】

 user_bp=Blueprint('user',__name__)

2. 在这个蓝图对象上进行操作,注册路由,指定静态文件夹,注册模版过滤器

 @user_bp.route('/')
 def user_profile():
     return 'user_profile'

3. 在应用对象上注册这个蓝图对象

 app.register_blueprint(user_bp)

1.3 单文件蓝图

        可以将创建蓝图对象与定义视图放到一个文件中 。

示例代码:

from flask import Flask, Blueprint

app = Flask(__name__)

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


@user_bp.route('/')
def user_profile():
    return 'user_profile'


#  注册蓝图
app.register_blueprint(user_bp)

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

运行效果:

1.4 指定蓝图的url前缀

在应用中注册蓝图时使用url_prefix参数指定

app.register_blueprint(user_bp, url_prefix='/user')
app.register_blueprint(goods_bp, url_prefix='/goods')

注意:在注册app.register_blueprint(book_bp, url_prefix="/book")或定义蓝图bp = Blueprint("book", __name__, url_prefix="/book")时,这两个地方只能一个地方定义url_prefix,若定义路径相同不受影响,若两个地方定义的不同的话,以app.register_blueprint(book_bp, url_prefix="/book")为准。

注意:两个地方同时指定url_prefix时不是路由的拼接。

示例代码1: 【只有在注册蓝图时写url_prefix】

from flask import Flask, Blueprint

app = Flask(__name__)

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


@user_bp.route('/')
def user_profile():
    return 'user_profile'


#  注册蓝图
app.register_blueprint(user_bp, url_prefix='/user')

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

运行效果:

示例代码2:【在注册蓝图和定义蓝图时写同一个url_prefix】

from flask import Flask, Blueprint

app = Flask(__name__)

#  创建蓝图对象
user_bp = Blueprint('user', __name__, url_prefix='/user')


@user_bp.route('/')
def user_profile():
    return 'user_profile'


#  注册蓝图
app.register_blueprint(user_bp, url_prefix='/user')

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

运行结果:

示例代码3:【在注册蓝图和定义蓝图时写不一样的url_prefix】

from flask import Flask, Blueprint

app = Flask(__name__)

#  创建蓝图对象
user_bp = Blueprint('user', __name__, url_prefix='/user_obj')


@user_bp.route('/')
def user_profile():
    return 'user_profile'


#  注册蓝图
app.register_blueprint(user_bp, url_prefix='/user')

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

运行结果:

2、蓝图的目录结构

        为了让项目代码更加清晰,可以通过将代码分在不同的文件里进行管理。

2.1 根据功能模块

        对于一个打算包含多个文件的蓝图,通常将创建蓝图对象放到Python包的 __init__.py 文件中。

--------- project # 工程目录
  |------ main.py # 启动文件
  |------ user  #用户蓝图
  |  |--- __init__.py  # 此处创建蓝图对象
  |  |--- passport.py  
  |  |--- profile.py
  |  |--- ...
  |
  |------ goods # 商品蓝图
  |  |--- __init__.py
  |  |--- ...
  |...

2.2 根据技术模块

--------- project # 工程目录
  |------ main.py # 启动文件
  |------ view  #用户蓝图
  |  |--- user.py  # 此处创建蓝图对象
  |  |--- item.py  
  |  |--- view.py
  |  |--- ...
  |...

2.3 实例代码

示例代码:

__init__.py

from flask import Blueprint

goods_bp = Blueprint('goods', __name__)

from . import views

views.py

from . import goods_bp


@goods_bp.route('/goods')
def get_goods():
    return 'get goods!'

main.py:

from flask import Flask, Blueprint

app = Flask(__name__)

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


@user_bp.route('/')
def user_profile():
    return 'user_profile'


#  注册蓝图
# app.register_blueprint(user_bp)
app.register_blueprint(user_bp, url_prefix='/user')

from goods import goods_bp
app.register_blueprint(goods_bp)

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

 运行效果:

3、蓝图中模板文件

3.1 蓝图内部模板目录

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

admin = Blueprint('admin',__name__,template_folder='my_templates')
bp = Blueprint('admin',__name__,url_prefix='/admin',template_folder='templates')

        模板文件和静态文件有点区别,以上代码写完以后,如果你渲染一个模板return render_template('user.html'),Flask默认会去项目根目录下的templates文件夹中查找user.html文件,如果找到了就直接返回,如果没有找到,才会去蓝图文件所在的目录下的templates文件夹中寻找。

注意

如果项目中的templates文件夹中有相应的模版文件,就直接使用了。

如果项目中的templates文件夹中没有相应的模版文件,那么就到在定义蓝图的时候指定的路径中寻找。

并且蓝图中指定的路径可以为相对路径,相对的是当前这个蓝图文件所在的目录

注意

  • 个性化coder喜欢在【创建蓝图对象的时候】 指定 模版文件的查找路径,如下
  • news_bp =Blueprint('news',__name__,url_prefix='/news',template_folder='news_page')
  • 只有确定templates目录下没有对应的 html文件名的时候,才会去蓝图文件指定的目录下查找,指定才会生效
  • 若templates目录下,有一个与蓝图文件指定的目录下同名的一个 html文件时,优先走templates目录下的东西

4、蓝图中静态文件

        和应用对象不同,蓝图对象创建时不会默认注册静态目录的路由。需要在创建时指定 static_folder 参数。

下面的示例将蓝图所在目录下的static_admin目录设置为静态目录

admin = Blueprint("admin",__name__,static_folder='static_admin')
app.register_blueprint(admin,url_prefix='/admin')

现在就可以使用/admin/static_admin/<filename>访问static_admin目录下的静态文件了。

也可通过static_url_path改变访问路径

admin = Blueprint("admin",__name__,static_folder='static_admin',static_url_path='/lib')
app.register_blueprint(admin,url_prefix='/admin')

        static_folder可以是相对路径(相对蓝图文件所在的目录),也可以是绝对路径。在配置完蓝图后,还有一个需要注意的地方是如何在模板中引用静态文件。在模板中引用蓝图,应该要使用蓝图名+.+static来引用,如下所示:

<link href="{{ url_for('user.static',filename='base.css') }}">

注意

查找方式1:查找静态文件时,正常情况下,会以static为根目录进行查找

<link href="{{ url_for('user.static',filename='news_list.css') }}" rel="stylesheet" type="text/css">

查找方式2:查找静态文件时,非正常情况下,需要用url_for('蓝图的名字.static'),然后会去蓝图对象在创建时指定的静态文件夹目录下 去查找静态文件

user_bp = Blueprint('user',__name__,url_prefix='/user',static_folder='user_statics')

<link href="{{ url_for('user.static',filename='user.css') }}" rel="stylesheet" type="text/css">

5、蓝图url_for函数

        如果使用蓝图,那么以后想要反转蓝图中的视图函数为url,就应该在使用url_for的时候指定这个蓝图名字。

        app类中、模版中、同一个蓝图类中都是如此。否则就找不到这个endpoint

        用url_for生成蓝图的url,使用的格式是:蓝图名称+.+视图函数名称。比如要获取user这个蓝图下的index视图函数的url,应该采用以下方式:

url_for('user.index')

        其中这个蓝图名称是在创建蓝图的时候,传入的第一个参数。bp = Blueprint('user',__name__,url_prefix='/user',template_folder='templates')。

html文件中写法:

<a href="{{ url_for('user.user_list')}}">新闻列表 OK写法</a>
{# <a href="{{ url_for('user_list')}}">新闻列表 no Ok写法</a>#}

蓝图使用url_for一个案例:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<div>
    图书列表URL:{{ book_url }} <br>
    用户列表URL:{{ user_url }}
</div>
</body>
</html>

main.py

from flask import Flask, render_template, url_for
from apps.book import bp as book_bp
from apps.user import bp as user_bp

app = Flask(__name__)
app.register_blueprint(book_bp, url_prefix="/book/")
app.register_blueprint(user_bp)


@app.route('/')
def index():
    data = {
        "book_url": url_for('book.book_list'),
        "user_url": url_for('user.user_list')
    }
    return render_template('index.html', **data)


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

book.py

from flask import Blueprint

bp = Blueprint("book", __name__, url_prefix="/book")


@bp.route('/list')
def book_list():
    return "图书列表"

user.py

from flask import Blueprint

bp = Blueprint("user", __name__, url_prefix="/user")


@bp.route('/list')
def user_list():
    return "用户列表"

运行效果:

6、蓝图中子域名实现

6.1 蓝图实现子域名

1. 使用蓝图技术。

2. 在创建蓝图对象的时候,需要传递一个 subdomain 参数,来指定这个子域名的前缀。

cms_bp=Blueprint('cms',__name__,subdomain='cms')

3. 需要在主app文件中,需要配置app.config的SERVER_NAME参数。例如:

app.config['SERVER_NAME']='sxt.com:5000'

4. 在windows: C:\Windows\System32\drivers\etc 下,找到hosts文件,然后添加域名与本机的映射。Linux: /etc/hosts

域名和子域名都需要做映射:
127.0.0.1 sxt.com
127.0.0.1 python.sxt.com

注意:

  • ip地址不能有子域名
  • localhost也不能有子域名

6.2 实例演示

配置hosts文件:

示例代码:

from flask import Flask, Blueprint

app = Flask(__name__)

app.config['SERVER_NAME'] = 'flask_test.com:5000'

#  创建蓝图对象
user_bp = Blueprint('user', __name__, url_prefix='/user', subdomain='user')


@app.route('/')
def index():
    return "返回首页!"


@user_bp.route('/')
def user_index():
    return '返回用户主页!'


#  注册蓝图
app.register_blueprint(user_bp)

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

运行结果:

  • 9
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值