我想创建一个Flask扩展,它依赖于另一个Flask扩展。为了争论,说它是Flask-Foo,并且需要Flask-Redis将一些特定数据存储在Redis数据库中。
我知道我可以向Flask-Redis添加安装依赖项。但是我不明白我应该如何实例化和初始化Flask-Redis。
Flask-Foo的设置设置了Flask-Redis对象。这样做的缺点是假设应用程序还没有使用Flask-Redis其他原因,在Flask-Foo之外明确配置。如果是,我们得到两个并排存在的对象,这似乎是错误的。
用户必须自己实例化并配置Flask-Redis。 Flask-Foo会检查它是否已为该应用初始化,否则会抱怨。这样做的问题在于它似乎对用户施加了样板 - 为什么他们必须设置Flask-Redis才能使用Flask-Foo,因为他们对Flask-Redis的配置没有其他知识或兴趣?此外,如果这意味着Flask-Foo.init_app()
之后必须始终调用Flask-Redis.init_app()
,我们是否会遇到麻烦?
不要使用Flask-Redis。直接使用Redis软件包,并在Flask-Foo代码中管理连接。这可能会避免上述问题。但它似乎不太优雅 - 我们基本上必须解决Flask-Redis解决的问题。如果Flask-Foo继续支持替代数据库,它将变得复杂,因为我们必须维护代码来管理不同类型的连接。
为了清楚起见,这不是一个特别关于Flask-Redis或它是如何工作的问题!我只想了解通常在扩展程序之上构建扩展的正确方法。
答案 0 :(得分:0)
Flask扩展与python模块具有相同的结构。您应该在setup.py文件中指定所有要求。 例如flask-babel
install_requires=[
'Flask',
'Babel>=2.3',
'Jinja2>=2.5'
],
答案 1 :(得分:0)
您可以将依赖扩展名传递给init_app。 http://flask.pocoo.org/docs/1.0/extensiondev/
class FooManager:
def __init__(self, app=None, db=None, **kwargs):
self.app = app
if app is not None:
self.init_app(app, db, **kwargs)
def init_app(self, app, db, **kwargs):
self.db = db
app.config.setdefault('xxx', xxx)
# Bind Flask-Foo to app
app.foo_manager = self
现在,您可以像这样从foo_manager
获取current_app
对象:
from flask import current_app
db = current_app.foo_manager.db
class XXX(db.Model):
pass
最后,也许您必须
with app.app_context():
FooManager(app, db) # or xx = FooManager(); xx.init_app(app, db)
很棒的依赖扩展对我们很有用。