轻量级的Web框架Flask 中模块化应用的实现
(编辑:jimmy 日期: 2024/12/1 浏览:3 次 )
Flask是一个轻量级的Web框架。虽然是轻量级的,但是对于组件一个大型的、模块化应用也是能够实现的,“蓝图”就是这样一种实现。对于模块化应用的实现,在Flask 0.2版本中进行了设计。本文暂时不对“蓝图”做详细的介绍,而是先从0.2版本中的Module类的实现讲起。其实,“蓝图”的实现和Module类的实现很相似。
为什么实现模块化应用
对于大型应用而言,随着功能的不断增加,整个应用的规模也会扩大。按照一定的规则将应用的不同部分进行模块化,不仅能够使整个应用逻辑清晰,也易于维护。例如,在Flask中,你也许想像如下构建一个简单的项目:
/myapplication /__init__.py /views /__init__.py /admin.py /frontend.py
以上目录结构中,我们将之前的Flask单文件修改成了一个应用包,所有的视图函数都在views下,并且按照功能分为了admin和frontend两个部分。为了实现这种模块化应用的构建,在0.2版本中Flask实现了Module类。这个类实例可以通过注册的方式,在Flask应用创建后添加进应用。
Module类实现了一系列的方法:
"htmlcode">
/myapplication /__init__.py /app.py /views /__init__.py /admin.py /blog.py
admin.py和blog.py两个模块的代码如下:
# admin.py from flask import Module admin = Module(__name__) @admin.route('/') def index(): return "This is admin page!" @admin.route('/profile') def profile(): return "This is profile page."
# blog.py from flask import Module blog = Module(__name__) @blog.route('/') def index(): return "This is my blog!" @blog.route('/article/<int:id>') def article(id): return "The article id is %d." % id
以上两个模块中,我们首先分别创建了一个Module类,然后像写一般的视图函数一样,为每个模块增加一些规则。之后,可以在创建Flask应用的时候将这些模块引入,就可以注册了。
# app.py from flask import Flask from views.admin import admin from views.blog import blog app = Flask(__name__) @app.route('/') def index(): return "This is my app." app.register_module(blog, url_prefix='/blog') app.register_module(admin, url_prefix='/admin') if __name__ == '__main__': from werkzeug.serving import run_simple run_simple('localhost', 5000, app)
在app.py中:
"htmlcode">
def register_module(self, module, **options): """Registers a module with this application. The keyword argument of this function are the same as the ones for the constructor of the :class:`Module` class and will override the values of the module if provided. """ options.setdefault('url_prefix', module.url_prefix) state = _ModuleSetupState(self, **options) for func in module._register_events: func(state)
通过以上代码可以发现:
"htmlcode">
> app.url_map Map([<Rule '/admin/profile' (HEAD, GET) -> admin.profile>, <Rule '/admin/' (HEAD, GET) -> admin.index>, <Rule '/blog/' (HEAD, GET) -> blog.index>, <Rule '/' (HEAD, GET) -> index>, <Rule '/blog/article/<id>' (HEAD, GET) -> blog.article>, <Rule '/static/<filename>' (HEAD, GET) -> static>] ) > app.url_map._rules_by_endpoint {'admin.index': [<Rule '/admin/' (HEAD, GET) -> admin.index>], 'admin.profile': [<Rule '/admin/profile' (HEAD, GET) -> admin.profile>], 'blog.article': [<Rule '/blog/article/<id>' (HEAD, GET) -> blog.article>], 'blog.index': [<Rule '/blog/' (HEAD, GET) -> blog.index>], 'index': [<Rule '/' (HEAD, GET) -> index>], 'static': [<Rule '/static/<filename>' (HEAD, GET) -> static>] } > app.view_functions {'admin.index': <function views.admin.index>, 'admin.profile': <function views.admin.profile>, 'blog.article': <function views.blog.article>, 'blog.index': <function views.blog.index>, 'index': <function __main__.index> }
这样,就可以把不同模块的URL规则放在一起,并在endpoint和视图函数之间形成对应关系。关于Flask应用中URL处理,可以参考:Flask应用中的URL处理。
下一篇:Python 模拟购物车的实例讲解