使用Factory pattern构建一个Flask App。
大多数Flask库使用init_app()
方法与工厂模式兼容
这里以Flask-RESTfull为例,但它适用于支持工厂模式的大多数其他库
文件夹结构和代码如下所示
flaskr/
├── __init__.py
└── resources
├── __init__.py
└── sample_resource.py
# flaskr/__init__.py
from flask import Flask
from flask_restful import Api
api = Api()
def create_app():
app = Flask(__name__)
from flaskr.resources import sample_resource # Resources need to be imported before calling init_app()
api.init_app(app)
return app
# flaskr/resources/sample_resource.py
from flask_restful import Resource
from flaskr import api
class UserResource(Resource):
def get(self):
return 'Sample Resource'
api.add_resource(UserResource, "/sample")
运行
$ export FLASK_APP=flaskr
$ flask run
我面临的问题是Resources
需要在范围内换句话说api.add_resource(UserResource, "/sample")
需要在^{api.init_app(app)
之前的所有资源
为了保持create_app()
干净,我在flaskr/resources/__init__.py
中添加了所有导入语句,并像这样导入resources
包
# flaskr/resources/__init__.py
from flaskr.resources import sample_resource
# flaskr/__init__.py
def create_app():
app = Flask(__name__)
from flaskr import resources
api.init_app(app)
这可以保持create_app()
的干净,但每次创建新资源时,我都需要在resources/__init__.py
中添加导入
指How to load all modules in a folder
这样__init__.py
文件将导入包中的所有资源。即使被接受的答案不起作用(我没有探究原因)
this answer成功了。因此,将文件更改为
# flaskr/resources/__init__.py
from importlib import import_module
from pathlib import Path
for f in Path(__file__).parent.glob("*.py"):
module_name = f.stem
if (not module_name.startswith("_")) and (module_name not in globals()):
import_module(f".{module_name}", __package__)
del f, module_name
del import_module, Path
这解决了整个问题,通过将上述代码添加到所有此类包(模型、模式)等,但对我来说,只需要选择文件名
以.py
结尾并导入所有这些内容并不优雅。出于某种原因,如果包中有非资源文件(即使是错误的)
它可能会导致问题(请记住,这不仅适用于Flask RESTfull,还适用于使用init_app()
的所有库)
init_app()
期间资源/模型需要在范围内李>PS:另一个库作为is-SQLAlchemy(或Flask-SQLAlchemy)应用,其中模型需要在范围内
在调用^{
因此-Flask app doesn't recognize flask_restful resources的答案不解决问题,因为它打破了工厂模式
目前没有回答
相关问题 更多 >
编程相关推荐