首页 > 解决方案 > 使用带有应用程序工厂的烧瓶邮件 - 将邮件属性添加到应用程序对象

问题描述

我正在使用带有应用程序工厂设计模式的 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)

这感觉像是在整个应用程序中访问邮件客户端的一种更简单的方法,而不是费力地确保您导入各种内容的顺序是正确的。

我想要的是有人告诉我为什么这不是一个好主意。

标签: pythonflaskflask-mail

解决方案


对我来说,正确的做法是定义一个扩展文件,其中包含诸如 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 变量。


推荐阅读