python之蓝图blueprint浅析

本文深入讲解Flask中的蓝图概念,包括蓝图的创建、运行机制、URL前缀设置、静态文件和模版目录注册,以及如何调整session配置。通过实例演示蓝图在项目中的应用,实现代码的模块化管理和路由分层。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 背景

一、python中的蓝图

二、创建蓝图

三、蓝图的运行机制

四、蓝图的url前缀

五、注册蓝图中的静态文件的相关路由

六、设置蓝图中模版的目录

七、调整session配置


 背景

由于我们现在的项目开发是一个相对于来说非常耗时间和精力的工程,如果我们将所有的Flask的请求方法都写在同一个文件下的话,非常不便于我们的代码的管理和后期的功能代码的添加。
       如下示例:我们在一个文件中写入多个路由,这会使代码维护变得困难。

       如图所示,如果我们将所有的请求方法写在同一个处理文件下面的话,会导致我们的代码显得很没有逻辑性,如果我们后期想要修改代码或者添加新的代码的话,就会显得很尴尬,不知道如何的下手,此时就需要我们的所谓的蓝图来解决这个问题了,如果学过django的程序员可能了解过django中的app的作用了,没错,django中的app的主要作用就是将django的项目分成一个个单独的app,然后将所有的app分配不同的处理功能,通过路由分配将它们连接成一个大的django项目,其实Flask中的蓝图和django中的app功能大同小异。

一、python中的蓝图

简单来说,Blueprint 是一个存储视图方法的容器,这些操作在这个Blueprint 被注册到一个应用之后就可以被调用,Flask 可以通过Blueprint来组织URL以及处理请求。

Flask使用Blueprint让应用实现模块化,在Flask中,Blueprint具有如下属性:

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

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

Blueprint对象用起来和一个应用/Flask对象差不多,最大的区别在于一个 蓝图对象没有办法独立运行,必须将它注册到一个应用对象上才能生效。

二、创建蓝图

1. 我们首先创建一个主路由配置文件manage.py,该文件主要的作用就是启动整个的Flask框架(项目),如图所示

2. 接着,我们在manage.py的平级的目录下创建两个文件admin.py、user.py,我们大概看一下两个文件中的内容:

      这两个文件相当于django中的两个app了,不同是django中的路由分配是将大的路由通过include分配给app的urls.py,而Flask是通过蓝图注册的方式将蓝图添加到主app中,user.py,admin.py中主要是创建蓝图,然后为创建的蓝图可以添加部分的路由配置。

3. 接着我们就可以在主路由文件manage.py中将我们创建的蓝图注册到主app中了。

       最后我们配置好了以后,就可以实现我们的路由分层管理了,我们来试一下,运行主程序manage.py

       我们在浏览器中访问我们所设置的路由

      

我们我请求的路由和我们所设置的返回值是一样的,这样我们就大概的完成了一个Flask的蓝图的注册,实现了文件功能的分层次管理了。

三、蓝图的运行机制

  • 蓝图是保存了一组将来可以在应用对象上执行的操作,注册路由就是一种操作
  • 当在app对象上调用 route 装饰器注册路由时,这个操作将修改对象的url_map路由表
  • 然而,蓝图对象根本没有路由表,当我们在蓝图对象上调用route装饰器注册路由时,它只是在内部的一个延迟操作记录列表defered_functions中添加了一个项
  • 当执行app对象的 register_blueprint() 方法时,应用对象将从蓝图对象的 defered_functions 列表中取出每一项,并以自身作为参数执行该匿名函数,即调用应用对象的 add_url_rule() 方法,这将真正的修改应用对象的usr_map路由表

四、蓝图的url前缀

  • 当我们在应用对象上注册一个蓝图时,可以指定一个url_prefix关键字参数(这个参数默认是/)

  • 在应用最终的路由表 url_map中,在蓝图上注册的路由URL自动被加上了这个前缀,这个可以保证在多个蓝图中使用相同的URL规则而不会最终引起冲突,只要在注册蓝图时将不同的蓝图挂接到不同的自路径即可
  • url_for在使用时,如果要生成一个蓝图里面的视图对应的路由地址,则需要声明当前蓝图名称+视图名称
url_for('users.home') # /users/home

五、注册蓝图中的静态文件的相关路由

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

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

# users/__init__.py,代码:
user_blu = Blueprint("users",__name__,static_folder='static_users')

# 启动文件 main.py,代码:
from users import user_blu
app.register_blueprint(user_blu,url_prefix='/users')

现在就可以使用/admin/static_admin/ 访问static_admin目录下的静态文件了 定制静态目录URL规则 :可以在创建蓝图对象时使用 static_url_path 来改变静态目录的路由。

下面的示例将为 static_admin 文件夹的路由设置为 /lib

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

六、设置蓝图中模版的目录

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

创建蓝图中的模板目录template_users :

admin = Blueprint('admin',__name__,template_folder='templates_users')

注:如果在 templates 中存在和 templates_users 有同名模板文件时, 则系统会优先使用 templates 中的文件

七、调整session配置

分析SQLAlachemy的构造方式可以发现,初始化并非一定要传递app应用对象到内部,事实上它提供了init_app方法给我们后续调用。而 init_app 方法是flask框架要求任何的第三方组件都要实现这个方法。

init_app方法内部就是要第三方组件开发者编写一些使用当前组建的默认配置项以及把当前组件设置成一个对象,加载到app对象内部extensions字典才能让开发者在flask框架内部配置和使用当前组件。

我们可以利用这种组件开发机制,那么把配置代码抽离出去。

配置文件中:

import redis
from flask_sqlalchemy import SQLAlchemy
# 创建db对象
db = SQLAlchemy()
class Config(object):
    DEBUG = True
    SECRET_KEY = "*(%#4sxcz(^(#$#8423"
    # 数据库链接配置:
    #数据类型://登录账号:登录密码@数据库主机IP:数据库访问端口/数据库名称
    SQLALCHEMY_DATABASE_URI = "mysql://root:123@127.0.0.1:3306/flask_students"
    # 设置mysql的错误跟踪信息显示
    SQLALCHEMY_TRACK_MODIFICATIONS = True
    # 打印每次模型操作对应的SQL语句
    SQLALCHEMY_ECHO = True

    """把session保存到redis中"""
    # session存储方式为redis
    # SESSION_TYPE="redis"
    # # 如果设置session的生命周期是否是会话期, 为True,则关闭浏览器session就失效
    # SESSION_PERMANENT = False
    # # 是否对发送到浏览器上session的cookie值进行加密
    # SESSION_USE_SIGNER = False
    # # 保存到redis的session数的名称前缀
    # SESSION_KEY_PREFIX = "session:"
    # # session保存数据到redis时启用的链接对象
    # SESSION_REDIS = redis.Redis(host='127.0.0.1', port='6379')  # 用于连接redis的配置

    SESSION_TYPE= 'sqlalchemy'  # session的存储方式为sqlalchemy
    SESSION_SQLALCHEMY= db  # SQLAlchemy对象
    SESSION_SQLALCHEMY_TABLE= 'sessions'  # session要保存的表名称
    SESSION_PERMANENT= True  # 如果设置为True,则关闭浏览器session就失效。
    SESSION_USE_SIGNER= False  # 是否对发送到浏览器上session的cookie值进行加密
    SESSION_KEY_PREFIX= 'session:'  # 保存到session中的值的前缀

启动文件main.py,代码:

from flask import Flask
from config import Config,db
from flask_session import Session

from flask import session

app = Flask(__name__,template_folder='templates')
app.config.from_object(Config)

# 把app加载到db对象中
db.init_app(app)

Session(app)

@app.route("/")
def index():
    return "ok"

@app.route("/set_session")
def set_session():
    """设置session"""
    session["username"] = "小明"
    return "ok"

if __name__ == '__main__':
    # db.create_all()
    print( app.url_map )
    app.run()

首先,我对蓝图的理解相对通俗,就是觉得蓝图对于视图方法模块化、大项目协同开发过程中的一个很好的工具. 1.下图是我们通常情况下使用的项目组织结构 看一下视图方法: #views.py 1 from app import app 2 3 4 @app.route('/user/index') 5 def index(): 6 return 'user_index' 7 8 @app.route('/user/show') 9 def show(): 10 return 'user_show' 11 12 @app.route('/user/add') 13 def add(): 14 return 'user_add' 15 16 @app.route('/admin/index') 17 def adminindex(): 18 return 'admin_index' 19 20 @app.route('/admin/show') 21 def adminshow(): 22 return 'admin_show' 23 24 @app.route('/admin/add') 25 def adminadd(): 26 return 'admin_add' #从视图方法中,我们看到有6个视图,分别对应admin,user两个不同用户的3个功能index,add,show. 这样写显然没问题,但是明显与python提倡的模块化,优雅的代码特点相违背,即不是很pythonpython代码. 让我们在这里假想两个问题: 1.如果admin和user不止只有3个功能呢,比如好几百个,导致views的代码量已经达到了上万行? 2.如果我们有多个同事分工开发admin,user和其它可能的模块呢,都同时往一个views里写代码吗,在做版本控制时,提交过程中频繁出现提交冲突了怎么办? 3.加入我们要抛弃admin或者user功能块时怎么办,要一一手动删除所有admin或是user相关的代码吗,这样当然可以,但是会不会太low呢? 当然根据Pythonic特点,我们肯定希望尽可能的把代码尽量的模块化,让我们的代码看起来更加的优雅和顺畅,这个时候flask.Blueprint(蓝图)就派上用场了 什么是蓝图? 一个蓝图定义了可用于单个应用的视图,模板,静态文件等等的集合。 我什么时候会用到蓝图蓝图的杀手锏是将你的应用组织成不同的组件,比如把这里的admin,user相关的视图方法分为两个组件,一个是admin组件,一个是user组件.这时我们可以 创建两个蓝图实现这两个独立的组件. 2.我们如何使用蓝本将上述的视图方法看上去更加pythonic呢? 由于上面的例子中只有两个组件(模块)admin,user,我们可以创建名为admin.py和user.py的两个文件,分别在里面创建两个蓝图的实例对象admin,user. 直接上代码: #admin.py #admin.py from flask import Blueprint,render_template, request admin = Blueprint('admin',__name__) @admin.route('/index') def index(): return render_template('admin/index.html') @admin.route('/add') def add(): return 'admin_add' @admin.route('/show') def show(): return 'admin_show' #要想创建一个蓝图对象,你需要import flask. Blueprint() 类并用参数 name 和 import_name 初始化。import_name通常用 __name__ ,一个表示当前模块的特殊的Python变量,作为 import_name 的取值。 #user.py from flask import Blueprint, render_template, redirect user = Blueprint('user',__name__) @user.route('/index') def index(): return render_template('user/index.html') @user.route('/add') def add(): return 'user_add' @user.route('/show') def show(): return 'user_show' 好了,视图函数已经分开了,我们如何使用它们的呢?再来看一下我们的views.py变成了什么样吧? #views.py from app import app from .admin import admin from .user import user #这里分别给app注册了两个蓝图admin,user #参数url_prefix='/xxx'的意思是设置request.url中的url前缀, #即当request.url是以/admin或者/user的情况下才会通过注册的蓝图的视图方法处理请求并返回 app.register_blueprint(admin,url_prefix='/admin') app.register_blueprint(user, url_prefix='/user') #现在我们的views是否已经变得很简单了呢?顺便回答第三个问题,如果想弃用某一个组件(模块)我们只需要相对应的注释掉给app注册蓝图的行即可. #细心的伙伴还可以发现,在views.py中在使用默认endpoint的前提下,我们是没有办法使用同一个视图方法名的(当然我们也不建议在同一个文件中有两个视图方法名相同, #尽管指向他们的request.url不同),但是使用了蓝图之后我们就可以在不同模块中使用相同的方法名了,例如add,show.. 3.到此我们就可以通过浏览器测试我们的程序 4.附上使用蓝图后的项目组织结构 当然如果项目不大的话就没有什么必要使用蓝图了,甚至我们可以把除了所有css,js,html的代码都写到一个文件中去,这里我们不在举例,说明.
How to build useful, real-world applications in the Python programming language Key Features Deliver scalable and high-performing applications in Python. Delve into the great ecosystem of Python frameworks and libraries through projects that you will build with this book. This comprehensive guide will help you demonstrate the power of Python by building practical projects. Book Description Python is a very powerful, high-level, object-oriented programming language. It's known for its simplicity and huge community support. Python Programming Blueprints will help you build useful, real-world applications using Python. In this book, we will cover some of the most common tasks that Python developers face on a daily basis, including performance optimization and making web applications more secure. We will familiarize ourselves with the associated software stack and master asynchronous features in Python. We will build a weather application using command-line parsing. We will then move on to create a Spotify remote control where we'll use OAuth and the Spotify Web API. The next project will cover reactive extensions by teaching you how to cast votes on Twitter the Python way. We will also focus on web development by using the famous Django framework to create an online game store. We will then create a web-based messenger using the new Nameko microservice framework. We will cover topics like authenticating users and, storing messages in Redis. By the end of the book, you will have gained hands-on experience in coding with Python. What you will learn Learn object-oriented and functional programming concepts while developing projects The dos and don'ts of storing passwords in a database Develop a fully functional website using the popular Django framework Use the Beautiful Soup library to perform web scrapping Get started with cloud computing by building microservice and serverless applications in AWS Develop scalable and cohesive microservices using the Nameko framework Create service dependencies for Redis and PostgreSQL Who This Book Is For This book is for software developers who are familiar with Python and want to gain hands-on experience with web and software development projects. A basic knowledge of Python programming is required. Table of Contents Implementing the Weather Application Creating a Remote-Control Application with Spotify Casting Votes on Twitter Exchange Rates and the Currency Conversion Tool Building a Web Messenger with Microservices Extending TempMessenger with a User Authentication Microservice Online Video Game Store with Django Order Microservice Notification Serverless Application
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慕城南风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值