python - 使用带有应用程序工厂的烧瓶邮件 - 将邮件属性添加到应用程序对象
问题描述
我正在使用带有应用程序工厂设计模式的 Flask 构建一个应用程序。我想在我的一个视图中使用 Flask-Mail,该视图通过蓝图注册到应用程序。
我从这个 Flask 中看到- cannot use Flask and Flask-mail instances from other files question 你应该在 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)
这感觉像是在整个应用程序中访问邮件客户端的一种更简单的方法,而不是费力地确保您导入各种内容的顺序是正确的。
我想要的是有人告诉我为什么这不是一个好主意。
解决方案
对我来说,正确的做法是定义一个扩展文件,其中包含诸如 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 调用您的 mail 变量。
推荐阅读
- angular - 在Angular NGXS中访问数组内的嵌套对象
- reactjs - React:HOC组件内部的触发方法
- android - TransformException:DexArchiveBuilderException:无法处理 \.gradle\caches\transforms-1\files-1.1\play-services-xxx-12.0.1.aar\xxx\classes.jar
- c# - 设置布尔值列表的最佳方法
- html - 如何从其他网站导入 CSS 自定义字体
- python - 为什么类方法名的前缀是类名,而不是其他对象?
- javascript - 如何在从 socket.io 实时获取数据更新时使用 D3 绘制时间戳(x 轴)和温度(y 轴)?
- vba - 如何动态创建元素的位置?
- reactjs - 如何在 React Bootstrap 中拦截并可能取消 onSelect?
- java - 如何将这两个数组相加成一个新数组?