Flask 应用的文件结构
时间:2011-02-17 来源:xuecan
/yourapplication /yourapplication /__init__.py /views __init__.py admin.py frontend.py /static /style.css /templates layout.html index.html login.html ...
视图保存在包 yourapplication.views 中。这里只需要放置一个空白的 __init__.py 文件即可。我们来看看包中的 admin.py 文件。首先,我们使用 Python 模块名称创建一个 Flask 模块(flask.Module)对象,这个对象行为上非常类似 flask.Flask 对象,它们大多数方法都是一样的。下面是一个易于理解的例子:
from flask import Module admin = Module(__name__) @admin.route('/') def index(): pass @admin.route('/login') def login(): pass @admin.route('/logout') def logout(): pass
对于 frontend.py 我们也可以做类似的处理,接下来,我们只需要确保在整个应用程序的 __init__.py 中注册这些模块即可:
from flask import Flask from yourapplication.views.admin import admin from yourapplication.views.frontend import frontend app = Flask(__name__) app.register_module(admin, url_prefix='/admin') app.register_module(frontend)
通过将这些模块注册到应用中,应用程序的 URL 映射表就能够适用于这些模块中的配置了。请注意 admin 模块的注册参数 url_prefix:默认的当我们注册一个模块时,缺省的 endpoint 是“/”,要使用其它的前缀,必须通过 url_prefix 参数配置。
使用 Flask 模块和直接使用 Flask 对象有什么区别呢?最主要的区别在 URL 生成的问题上。例如,我们经常使用的 url_for() 函数,当直接与 Flask 对象一起工作时,它的第一个参数,也就是所谓的 endpoint,是视图函数的名称,而当结合 Flask 模块一起工作时,对于同一个模块中的视图函数,用法仍然一样,而对于别的模块中的函数,则需要使用模块名加上句点作为前缀。看看下面的例子可以帮助我们更容易的理解这个问题。假设我们在 admin 模块中有一个需要重定向到 frontend 模块的函数,它看起来类似这样:
@admin.route('/to_frontend') def to_frontend(): return redirect(url_for('frontend.index')) @frontend.route('/') def index(): return "I'm the frontend index"
而如果我们只需要重定向到相同模块中的其它函数,那么我们既可以使用完成的 endpoint 路径,也可以只使用函数名:
@frontend.route('/to_index') def to_index(): return redirect(url_for('index')) @frontend.route('/') def index(): return "I'm the index"
更进一步,如果我们的 Module 对象是放在 Python 包中的,这样,我们有增加了额外的放置模板和静态文件的位置。假设我们的应用程序看起来像是这样的:
/yourapplication __init__.py /apps __init__.py /frontend __init__.py views.py /static style.css /templates index.html about.html ... /admin __init__.py views.py /static style.css /templates list_items.html show_item.html ...
这些包中的静态目录将会被自动展开为 URL。假设这个 admin 模块是通过 /admin 前缀展现在 URL 中的,那么可以通过 /admin/static/style.css 来访问其中的样式表文件。而该文件的 endpoint 则是 'admin.static'。
与 URL 规则可以省略前缀不同,我们总是需要使用完成的模块名称来引用模板,例如: render_template('admin/list_items.html') 等等。同样的,既然我们的视图函数已经从 yourapplication.views.admin 移动到 yourapplication.apps.admin.views 中了,我们需要在注册模块的时候明确的设置一个名称。这是由于再使用 __name__ 作为参数的话它这时候的值是 views 了:
# in yourapplication/apps/admin/views.py admin = Module(__name__, 'admin')
同样的,引导程序也需要稍作调整:
# in yourapplication/__init__.py from flask import Flask from yourapplication.apps.admin.views import admin from yourapplication.apps.frontend.views import frontend app = Flask(__name__) app.register_module(admin, url_prefix='/admin') app.register_module(frontend)
值得注意的是,如果我们使用一个不合格的 endpoint,默认的 Flask 会将它当作是模块的静态文件目录,即便这个目录并不存在。这对于任何 endpoint 都有效,而不仅仅是名为 static 的目录,只不过通常我们使用 static 放置静态文件而非设置一个视图函数而已。如果需要使用整个应用程序的静态目录,可以在最开始加上一个句点:
# this refers to the application's static folder url_for('.static', filename='static.css') # this refers to the current module's static folder url_for('static', filename='static.css')