用户在 Flask 上注册后发送邮件时出现循环导入问题

Posted

技术标签:

【中文标题】用户在 Flask 上注册后发送邮件时出现循环导入问题【英文标题】:Circular import issue when working with sending mail upon user registration on Flask 【发布时间】:2018-11-02 19:54:25 【问题描述】:

我目前正在使用烧瓶应用程序,并尝试在用户注册该站点后发送电子邮件。我在实例化应用程序的 main.py 和将数据提交到数据库并将密码通过电子邮件发送回用户的 data_inserts.py 之间进行循环导入时遇到困难。对于电子邮件功能,我使用 Flask-mail 扩展。我得到的错误如下:

ImportError: Cannot import name from 'DataInserts' from relevant_folder.data_inserts

以下是详细信息:

main.py:

from relevant_folder.data_inserts import DataInserts
from flask import Flask
from flask_mail import Mail
from conf.mail_settings.py import mail_settings

app = Flask(__name__)
app.config.update[mail_settings]
mail = Mail(app)

@app.route("/register")
def register():
    params = request.json
    DataInserts.add_user(params)

relevant_folder.data_inserts.py:

from main import app
from main.app import mail
from flask_mail import message 

class DataInserts():
    def add_user(self, new_user_json):
        ''' add user name and email to db logic goes here'''
        msg = Message(subject="Subject",
                  sender=app.config.get("MAIL_USERNAME"),
                  recipients=[new_user_json["email"]],
                  body="Hello " + new_user_json["name"] + ", your password is password")
        mail.send(msg)

我觉得我的应用程序结构不正确。非常感谢任何帮助

【问题讨论】:

【参考方案1】:

移动 DataInserts 导入应该就足够了...

from flask import Flask
from flask_mail import Mail
from conf.mail_settings.py import mail_settings

app = Flask(__name__)
app.config.update[mail_settings]
mail = Mail(app)

from relevant_folder.data_inserts import DataInserts

@app.route("/register")
def register():
    params = request.json
    DataInserts.add_user(params)

或者,您可以将应用程序和邮件实例传递给 DataInsert 类,而不是导入全局变量...

更新:另一种方法是使用“flask.current_app”。

from relevant_folder.data_inserts import DataInserts
from flask import Flask
from flask_mail import Mail
from conf.mail_settings.py import mail_settings

app = Flask(__name__)
app.config.update[mail_settings]
mail = Mail(app)
app.mail = mail

@app.route("/register")
def register():
    params = request.json
    DataInserts.add_user(params)

请注意,我将邮件实例存储在 app.mail 以方便以后访问。

relevant_folder.data_inserts.py:

from flask import current_app
from flask_mail import message 

class DataInserts():
    def add_user(self, new_user_json):
        ''' add user name and email to db logic goes here'''
        msg = Message(subject="Subject",
                  sender=current_app.config.get("MAIL_USERNAME"),
                  recipients=[new_user_json["email"]],
                  body="Hello " + new_user_json["name"] + ", your password is password")
        current_app.mail.send(msg)

但请记住,current_app 需要一个活动的应用程序上下文。 在处理请求时,上下文应该始终存在,否则您可以手动创建上下文,例如使用with app.app_context():

有关该主题的更多信息,请参阅烧瓶文档: http://flask.pocoo.org/docs/1.0/appcontext/

【讨论】:

我仍然遇到同样的错误。我可能应该提到这一点,但我还有一些其他蓝图注册到应用程序并使用 DataInserts 好吧,想一想:在 main 中,在实例化应用程序之前,您导入 DataInserts - 在 DataInserts 中,您从 main 导入应用程序,此时尚不存在... True @Sebastian 我了解问题的原因,但不知道如何解决 感谢@Sebastian......使用current_app,我能够成功地将用户数据写入数据库。但是当它尝试发送邮件时出现以下错误:AttributeError: 'Flask' object has no attribute 'mail' 好像没有current_app.mail对象

以上是关于用户在 Flask 上注册后发送邮件时出现循环导入问题的主要内容,如果未能解决你的问题,请参考以下文章

Flask入门邮件同步与异步发送

Flask-Mail 队列消息被发送到不同的电子邮件

Java Mail:在没有 SSL 的端口 25 上发送电子邮件时出现 SSLHandshakeException

Flask发送注册邮件

通过 Firebase 函数发送电子邮件时出现 Firebase SendGrid 错误 - 错误:错误请求

使用用户名 = 电子邮件保存用户时出现 IntegrityError