如何将Flask应用划分为多个py文件?

问题:如何将Flask应用划分为多个py文件?

我的flask应用程序当前包含一个test.py具有多个路由和已main()定义路由的文件。有什么办法可以创建一个test2.py文件,其中包含未处理的路由test.py

@app.route('/somepath')
def somehandler():
    # Handler code here

我担心其中包含太多路由,test.py并且希望使其运行python test.py,这样我也可以test.py像使用同一文件一样提取这些路由。为了使此功能正常运行,我必须进行哪些更改test.py和/或进行哪些更改test2.py

My flask application currently consists of a single test.py file with multiple routes and the main() route defined. Is there some way I could create a test2.py file that contains routes that were not handled in test.py?

@app.route('/somepath')
def somehandler():
    # Handler code here

I am concerned that there are too many routes in test.py and would like to make it such that I can run python test.py, which will also pick up the routes on test.py as if it were part of the same file. What changes to I have to make in test.py and/or include in test2.py to get this to work?


回答 0

您可以使用常规的Python包结构将您的应用分为多个模块,请参见Flask文档。

然而,

Flask使用蓝图的概念来制作应用程序组件并支持应用程序内或跨应用程序的通用模式。

您可以在单独的文件中将应用程序的子组件创建为蓝图:

simple_page = Blueprint('simple_page', __name__, template_folder='templates')
@simple_page.route('/<page>')
def show(page):
    # stuff

然后在主要部分中使用它:

from yourapplication.simple_page import simple_page

app = Flask(__name__)
app.register_blueprint(simple_page)

蓝图还可以捆绑特定资源:模板或静态文件。请参阅Flask文档以获取所有详细信息。

You can use the usual Python package structure to divide your App into multiple modules, see the Flask docs.

However,

Flask uses a concept of blueprints for making application components and supporting common patterns within an application or across applications.

You can create a sub-component of your app as a Blueprint in a separate file:

simple_page = Blueprint('simple_page', __name__, template_folder='templates')
@simple_page.route('/<page>')
def show(page):
    # stuff

And then use it in the main part:

from yourapplication.simple_page import simple_page

app = Flask(__name__)
app.register_blueprint(simple_page)

Blueprints can also bundle specific resources: templates or static files. Please refer to the Flask docs for all the details.


回答 1

我想推荐GitHub上的flask-empty

它提供了一种理解蓝图,多个视图和扩展的简便方法。

I would like to recommend flask-empty at GitHub.

It provides an easy way to understand Blueprints, multiple views and extensions.


回答 2

您可以使用简单的技巧,即从另一个文件内的main导入flask应用程序变量,例如:

test-routes.py

from __main__ import app

@app.route('/test', methods=['GET'])
def test():
    return 'it works!'

在您的主文件中,声明flask app的位置,导入测试路由,例如:

app.py

from flask import Flask, request, abort

app = Flask(__name__)

# import declared routes
import test-routes

它从我这边起作用。

You can use simple trick which is import flask app variable from main inside another file, like:

test-routes.py

from __main__ import app

@app.route('/test', methods=['GET'])
def test():
    return 'it works!'

and in your main files, where you declared flask app, import test-routes, like:

app.py

from flask import Flask, request, abort

app = Flask(__name__)

# import declared routes
import test-routes

It works from my side.


回答 3

将应用程序划分为多个蓝图是一个好主意。但是,如果这还不够,并且您想将蓝图本身分成多个py文件,也可以使用常规的Python模块导入系统,然后遍历从其他文件导入的所有路由来实现。

我使用以下代码创建了一个Gist:

https://gist.github.com/Jaza/61f879f577bc9d06029e

据我所知,这是目前划分蓝图的唯一可行方法。尽管存在很多与此相关的话题,但在Flask中无法创建“子蓝图”:

https://github.com/mitsuhiko/flask/issues/593

另外,即使有可能(并且可以使用该问题线程中的一些代码片段来实现),子蓝图对于您的用例也可能过于严格-例如,如果您不希望所有路线都在子模块具有相同的URL子前缀。

Dividing the app into blueprints is a great idea. However, if this isn’t enough, and if you want to then divide the Blueprint itself into multiple py files, this is also possible using the regular Python module import system, and then looping through all the routes that get imported from the other files.

I created a Gist with the code for doing this:

https://gist.github.com/Jaza/61f879f577bc9d06029e

As far as I’m aware, this is the only feasible way to divide up a Blueprint at the moment. It’s not possible to create “sub-blueprints” in Flask, although there’s an issue open with a lot of discussion about this:

https://github.com/mitsuhiko/flask/issues/593

Also, even if it were possible (and it’s probably do-able using some of the snippets from that issue thread), sub-blueprints may be too restrictive for your use case anyway – e.g. if you don’t want all the routes in a sub-module to have the same URL sub-prefix.


回答 4

使用集中式URL映射,无需蓝图和棘手的导入即可完成此任务

app.py

import views
from flask import Flask

app = Flask(__name__)

app.add_url_rule('/', view_func=views.index)
app.add_url_rule('/other', view_func=views.other)

if __name__ == '__main__':
    app.run(debug=True, use_reloader=True)

views.py

from flask import render_template

def index():
    return render_template('index.html')

def other():
    return render_template('other.html')

This task can be accomplished without blueprints and tricky imports using Centralized URL Map

app.py

import views
from flask import Flask

app = Flask(__name__)

app.add_url_rule('/', view_func=views.index)
app.add_url_rule('/other', view_func=views.other)

if __name__ == '__main__':
    app.run(debug=True, use_reloader=True)

views.py

from flask import render_template

def index():
    return render_template('index.html')

def other():
    return render_template('other.html')