Flask蓝本(blueprint)

上一章我们是将所有的Flask的请求方法都写在同一个文件下,这种方式非常不便于我们的代码管理及后期的维护,此时就需要所谓的蓝本来解决这个问题了。

我们知道,Django中的app的主要作用就是将Django的项目分成一个个单独的app,然后将所有的app分配不同的处理功能,通过路由分配将它们连接成一个大的Django项目,其实Flask中的蓝本和Django中的app功能大同小异,下面我们大概的学习一下Flask的蓝本。

一 小型应用

1.1 目录结构

image_thumb2

1.2 相应代码

account.py

from flask import Blueprint,render_template

account = Blueprint('account',__name__)  # 蓝本通过实例化一个Blueprint类对象创建,且必须包含两个指定参数:名称和蓝本所在的包或模块,与应用一致,多数情况下第二个参数使用__name__
# 自定义静态文件,模板文件路径,系统会优先在templates,static中寻找,没有则在指定的路径中寻找
# account = Blueprint('account',__name__,template_folder='xxx')

@account.route('/login')
def login():   # 视图函数的名字不能和蓝本对象的名字一致
    return render_template('login.html')

@account.route('/logout')
def logout():
    return 'Logout'
View Code

user.py

from flask import Blueprint

user = Blueprint('user',__name__)

@user.route('/list')
def list():
    return 'List'

@user.route('/detail')
def detail():
    return 'Detail'
View Code

views/__init__.py

from flask import Flask

# 导入蓝本
from .views.account import account
from .views.user import user

app = Flask(__name__)

# 把蓝本注册到app中
app.register_blueprint(account)
app.register_blueprint(user,url_prefix = '/api')   # 指定前缀路径,访问路径:http://127.0.0.1:5000/api/...
View Code

manage.py

from flask_crm import app

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

二 大型应用

2.1 目录结构

image_thumb4

2.2 相应代码

admin/views.py

from . import admin


@admin.route('/index')
def index():
    return 'Admin.Index'
View Code

admin/__init__.py

from flask import Blueprint

admin = Blueprint(
    'admin',
    __name__,
    template_folder='templates',
    static_folder='static'
)
from . import views  # 该部分视图保存在views.py中,导入该模块就能把路由与蓝本关联起来。有其他部分,也需要一起导入,比如:errors.py(自定义错误画面)
# 注意:必须在__init__.py脚本的末尾导入,这是为了避免循环导入依赖,因为在app/auth/views.py中还要导入auth蓝本,
# 所以除非循环引用出现在定义auth之后,否则会致使导入出错。
View Code

web/views.py

from . import web


@web.route('/index')
def index():
    return 'Web.Index'
View Code

web/__init__.py

from flask import Blueprint

web = Blueprint(
    'web',
    __name__,
    template_folder='templates',
    static_folder='static'
)
from . import views
View Code

__init__.py

from flask import Flask
from .admin import admin
from .web import web


app = Flask(__name__)   # 可以创建一个函数,def create_app():app=Flask(__name__),启动文件先创建app=create_app(),再使用app.run()
app.debug = True

app.register_blueprint(admin, url_prefix='/admin')
app.register_blueprint(web)
View Code

manage.py

from flask_crm2 import app

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

三 扩展

3.1 特殊装饰器的使用

我们以before_request为例进行说明:

全局使用

from flask import Flask

# 导入蓝本
from .views.account import account
from .views.user import user

app = Flask(__name__)

# 全局使用before_request
@app.before_request
def x1():
    print('app.brfore request')

# 把蓝本注册到app中
app.register_blueprint(account)
app.register_blueprint(user)
View Code

单独使用

from flask import Blueprint,render_template

account = Blueprint('account',__name__)
# 自定义静态文件,模板文件路径,系统会优先在templates,static中寻找,没有则在指定的路径中寻找
# account = Blueprint('account',__name__,template_folder='xxx')

# 单独使用before_request
@account.before_request
def x1():
    print('app.brfore request')


@account.route('/login')
def login():   # 视图函数的名字不能和蓝本对象的名字一致
    return render_template('login.html')

@account.route('/logout')
def logout():
    return 'Logout'
View Code

3.2 子域名

蓝本子域名:xxx = Blueprint(xxx,  __name__, subdomain='admin')
# 前提需要给配置SERVER_NAME: app.config['SERVER_NAME'] = 'joe1991.com:5000'
# 访问时:admin.'joe1991.com:5000/login

以小型应用举例:

account.py

from flask import Blueprint,render_template

account = Blueprint('account',__name__,subdomain='admin')

@account.route('/login')
def login():
    return render_template('login.html')

@account.route('/logout')
def logout():
    return 'Logout'
View Code

__init__.py

from flask import Flask

# 导入蓝本
from .views.account import account
from .views.user import user

app = Flask(__name__)
app.config['SERVER_NAME'] = 'joe1991.com:5000'

# 把蓝本注册到app中
app.register_blueprint(account)
app.register_blueprint(user,url_prefix = '/api')
View Code

访问效果:

image_thumb6

四 其他补充

4.1 一个完整的应用结构

flask_blog
├─app/  # Flask应用一般保存在名为app的包中,包括所有代码、模板、静态文件,可以改为其他名字
│  │  xxx.py  # 其他文件,比如:电子邮件支持函数等
│  │  models.py   # 数据库模型
│  │  __init__.py  # 应用的构造文件,应用的工厂函数就在构造文件中定义,注册蓝本也在此完成
│  │          
│  ├─auth/  # 蓝本auth
│  │  │  forms.py  # 蓝本auth中定义的表单程序
│  │  │  views.py  # 蓝本auth中定义的应用路由
│  │  │  __init__.py  # 创建蓝本
│  │          
│  ├─main/  # 蓝本main
│  │  │  errors.py  # 蓝本main中定义的错误处理程序
│  │  │  forms.py  # 蓝本main中定义的表单程序
│  │  │  views.py  # 蓝本main中定义的应用路由
│  │  │  __init__.py    # 创建蓝本      
│  ├─static/   # 存放静态文件          
│  ├─templates/  # 存放模板文件
├─tests/  # 单元测试在tests包中编写
│  │  test_basics.py
│  │  __init__.py
│          
├─migrations/   # 数据库迁移脚本在该文件夹中                      
├─venv/   # Python虚拟环境在该文件夹中
├─requirements.txt   # 列出所有的依赖包,便于在其他计算机中重新生成相同的虚拟环境
│                    # 该文件可由pip自动生成:pip freeze >requirements.txt
│                    # 如果想创建这个虚拟环境的完整副本,先创建一个新的虚拟环境,然后在其中运行:pip install -r requirements.txt
├─blog_run.py  # 主脚本(定义Flask应用实例,同时还有一些辅助管理应用的认为)
├─config.py  # 存储配置

4.2 虚拟环境

安装Flask最便捷的方法就是使用虚拟环境。何为虚拟环境?虚拟环境是Python解释器的一个私有副本,在这个环境中我们可以安装私有包,而且不会影响系统中安装的全局Python解释器。

虚拟环境非常有用,可以避免我们安装的Python版本和包与系统预装的发生冲突,为每个项目单独创建虚拟环境,可以保证应用只能访问所在虚拟环境中的包,从而保持全局解释器的干净整洁,使其只作为创建更多虚拟环境的源。与直接使用系统全局的Python解释器相比,使用虚拟环境还有个好处,那就是不需要管理员权限。

4.2.1 如何在Python3中创建虚拟环境?

Python和Python2解释器创建虚拟环境的方法有所不同。在Python3中,虚拟环境由Python标准库中的venv包原生支持。

如果是Ubantu Linux系统预装的Python3,那么标准库中没有venv包,则我们需要先安装python3-venv包:

$ sudo apt-get install python3-venv

然后再创建虚拟环境,命令格式如下:

$ python3 -m venv virtual-environment-name

-m venv选项的作用是以独立的脚本运行标准库中的venv包,后面的参数为虚拟环境的名称。

如果我们需要在xxx目录中创建一个虚拟环境,如下操作(我们需要确保当前目录是xxx):

$ python3 -m venv venv

这个命令执行完成后,xxx目录中会出现一个名为venv的子目录(通常虚拟环境的名称为venv,我们也可以修改为其他名称),这就是一个全新的虚拟环境,包含这个项目专用的Python解释器。

4.2.2 如何在Python2中创建虚拟环境?

python2中没有集成venv包。这一版解释器需要使用第三方工具virtualenv创建虚拟环境。同样的需要确保在特定文件夹中(比如:xxx),然后根据自己的操作系统,执行操作。

如果是Linux或MacOS,执行命令:

$ sudo pip install virtualenv

如果是win,以“管理员身份运行”打开终端,执行命令:

$ pip install virtualenv

virtualenv命令的参数是虚拟环境的名称,确保当前目录是xxx,然后执行下述命令创建名为venv的虚拟环境:

$ virtualenv venv

这个命令在当前目录中创建一个名为venv的子目录,虚拟环境相关的文件都在这个子目录中。

4.2.3 使用虚拟环境

若想使用虚拟环境,要先将其激活。如果是Linux或MacOS,执行命令:

$ source venv/bin/activate

如果是win,执行命令:

$ venv\Scripts\activate

虚拟环境被激活后,里面的Python解释器的路径会被添加到当前命令会话的PATH环境变量中,指明在什么位置寻找一众可执行文件。为了提醒以激活虚拟环境,激活虚拟环境的命令会修改命令提示符,加入环境名:

(venv) $

激活虚拟环境后,在命令提示符中输入python,将调用虚拟环境中的解释器,而不是系统全局解释器。如果同时打开多个命令提示符窗口,每个窗口都需要激活。

虚拟环境中的工作结束后,在命令提示符中输入deactivate,还原当前终端会话的PATH环境变量,把命令提示符重置为最初的状态。

补充说明:不激活也可以使用虚拟环境:

# 在Linux或MacOS执行
venv/bin/python,
# 在win中执行
venv\Scripts\python

一个小知识点:任何时候我们可以通过pip freeze命令查看虚拟环境中安装了那些包。

4.3 Web开发服务器

Flask应用自带Web开发服务器,通过flask run命令运行。这个命令在FLASK_APP环境变量指定的Python脚本中寻找应用实例。

若我们想执行上面的应用,首先确保之前创建的虚拟环境已激活,而且里面安装了Flask。  Linux或MacOS用户执行下述命令启动Web服务器:

(venv) $ export FLASK_APP = blog_run.py
(venv) $ flask run

如果是win,则执行如下命令:

(venv) $ set FLASK_APP = blog_run.py
(venv) $ flask run

服务器启动后便开始轮询,处理请求。直到按Ctrl+C键停止服务器,轮询才结束。

补充说明:Flask提供的Web服务器只适用于开发和测试。

Flask Web开发服务器也可以通过编程的方式启动:

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

调试模式

Flask应用可以在调试模式中运行。在这个模式下,开发服务器默认会加载两个便利的工具:重载器调试器

调试模式默认禁用,如果想启用,在flask run之前需先设定FLASK_DEBUG=1环境变量。

如果想以编程的方式启动调试模式,就使用app.run(debug=1)。

4.4 命令行选项

flask命令支持一些选项。执行flask --help,或者执行flask而不提供任何参数,可以参看那些选项可用:

(venv) $ flask --help
Usage: flask [OPTIONS] COMMAND [ARGS]...
...
    > set FLASK_APP=hello.py
    > flask run
Options:
  --version  Show the flask version
  --help     Show this message and exit.

Commands:
  db      Perform database migrations.
  routes  Show the routes for the app.
  run     Runs a development server.
  shell   Runs a shell in the app context.
View Code

flask shell命令在应用的上下文中打开一个python shell会话。在这个会话中可以运行维护任务或测试,也可以调试问题。

(venv) $ flask run --help
Usage: flask run [OPTIONS]

  Run a local development server.

  ...

Options:
  -h, --host TEXT                 The interface to bind to.
  -p, --port INTEGER              The port to bind to.
  --cert PATH                     Specify a certificate file to use HTTPS.
  --key FILE                      The key file to use when specifying a
                                  certificate.
  --reload / --no-reload          Enable or disable the reloader. By default
                                  the reloader is active if debug is enabled.
  --debugger / --no-debugger      Enable or disable the debugger. By default
                                  the debugger is active if debug is enabled.
  --eager-loading / --lazy-loader
                                  Enable or disable eager loading. By default
                                  eager loading is enabled if the reloader is
                                  disabled.
  --with-threads / --without-threads
                                  Enable or disable multithreading.
  --help                          Show this message and exit.
flask run --help

--host参数特别有用,它告诉Web服务器在那个网络接口上监听客户端发来的连接。默认情况下,Flask的Web服务器监听localhost上的连接,因此服务器只接收运行服务器的计算机发送连接。下述命令让Web服务器监听公共网络接口上的连接,因此同一网络中的其他计算机发送的连接也可以接收到:

(venv) $ flask run -- host 0.0.0.0

如果想以编程的方式实现,就使用:

app.run(host=’0.0.0.0’)


参考:https://www.cnblogs.com/wupeiqi/articles/7552008.html

posted @ 2019-09-09 19:22  Joe1991  阅读(280)  评论(0)    收藏  举报