我正在使用带有应用程序工厂设计模式的Flask构建应用程序。我想在其中一个视图中使用Flask-Mail,并通过一个蓝图注册到该应用程序。
我从这个Flask - cannot use Flask and Flask-mail instances from other files问题中看到,您应该像这样在create_app()函数外部实例化Mail()对象:
from flask_mail import Mail
mail = Mail()
def create_app(config_lvl):
# stuff
mail.init_app(app)
# more stuff
return app
然后,您可以将邮件对象导入视图文件并从那里访问它。
为此,您需要确保在导入包含使用邮件对象的视图的蓝图之前,在应用程序中__init__.py
中实例化邮件对象。如果不这样做,则会出现导入错误。
对我来说,这感觉很棘手,尽管Flask有时似乎对这种事情感到很满意,但我希望应用程序工厂设计模式可以最大程度地减少这种引入的麻烦。
我的解决方案是将邮件客户端附加到应用程序对象,以便可以使用current_app.mail
从其他任何地方访问它,如下所示:
## __init.py __ ##
from flask_mail import Mail
def create_app(config_lvl):
# stuff
app.mail = Mail(app)
# more stuff
return app
## views.py ##
from flask_mail import Message
from flask import current_app
def send_email(to, subject, template):
msg = Message(
subject,
recipients=[to],
html=template,
sender=current_app.config['MAIL_DEFAULT_SENDER']
)
current_app.mail.send(msg)
这就像在整个应用中访问邮件客户端的一种简单方法,而不是费力地确保导入各种内容的顺序正确。
我想要的是让某人告诉我为什么这不是一个好主意。
答案 0 :(得分:0)
对我来说,正确的方法是定义一个扩展文件,其中包含烧瓶扩展的实例,例如Mail。在extensions.py
中from flask-mail import Mail
mail = Mail()
,然后通过create_app函数调用您的邮件。
from extension import mail
def create_app(config_lvl):
mail.init_app(app)
return app
之后,您可以在所有项目中从extensions.py调用邮件变量。