我希望使用flask-mail将电子邮件验证添加到我的Web应用程序中,并且在阅读了文档之后,似乎必须使用以下命令创建一个Mail实例:
app = Flask(__name__)
mail = Mail(app)
,然后导入应用程序和邮件实例。
但是,我当前的代码在函数内部创建了Flask和Mail实例,如下所示:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config["SECRET_KEY"] = "9OLWxND4o83j4K4iuopO"
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///db.sqlite"
db.init_app(app)
login_manager = LoginManager()
login_manager.login_view = "auth.login"
login_manager.init_app(app)
from .models import User
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
return app
上面的代码在我的__init__.py
文件中。
我无法将Mail实例导入我在其中注册用户的其他文件中,因为实际上并没有定义用户,它只是在函数中。
基本代码来自本教程:https://www.digitalocean.com/community/tutorials/how-to-add-authentication-to-your-app-with-flask-login,现在我向其中添加电子邮件验证。
要运行Web应用程序,请在Python REPL中键入db.create_all(app=create_app())
,这将创建我的sqlite数据库,这是唯一一次调用create_all()函数。然后在Powershell终端中输入Flask run
。
答案 0 :(得分:0)
解决方案是两阶段初始化,几乎所有Flask
扩展都支持:
from flask import Flask
from flask_mail import Mail
mail = Mail()
def create_app():
app = Flask(__name__)
...
mail.init_app(app)
...
这允许您从另一个模块导入mail
。
我最近刚刚实施了电子邮件验证,并且遵循了这个古老但仍然有效的教程:
http://www.patricksoftwareblog.com/confirming-users-email-address/
答案 1 :(得分:0)
与许多其他扩展一样,安装 mail
后,您需要在 __init__.py
文件中创建一个 flask-mail
对象。使用如下所示的结构,其中使用了蓝图,您可以为您的 Flask 应用添加电子邮件支持。
project_folder
| --- app.py
| --- config.py
| --- app/
| --- email.py
| --- models.py
| --- __init__.py
| --- main/
| --- __init__.py
| --- routes.py
| --- email.py
| --- auth/
| --- __init__.py
| --- routes.py
| --- templates/
| --- auth/
| --- register.html
在应用程序工厂中创建一个 mail
对象:
# app/__init.py
from flask import Flask
from flask_mail import Mail
# ...
mail = Mail()
# ...
def create_app():
app = Flask(__name__)
# ...
mail.init_app(app)
# ...
创建一个电子邮件模块,它将处理您的应用程序的所有电子邮件支持需求,如下所示:
# app/email.py
from threading import Thread
from flask import current_app
from flask_mail import Message
from app import mail
def send_async_email(app, msg):
with app.app_context():
mail.send(msg)
def send_email(subject, sender, recipients, text_body, html_body):
msg = Message(subject, sender=sender, recipients=recipients)
msg.body = text_body
msg.html = html_body
Thread(target=send_async_email,
args=(current_app._get_current_object(), msg)).start()
上面,我已经导入了我们在 mail
文件中创建的 __init__.py
。由于我们使用的是工厂函数,因此我从 Flask 导入 current_app
,这将有助于访问应用程序的配置变量。这些变量是完成电子邮件支持所必需的。线程确保在执行电子邮件设置时不会减慢应用程序的速度。
我假设您想向已注册的用户发送电子邮件。因此,在 auth
包中,您需要创建一个辅助方法来将电子邮件发送给用户。
# app/auth/email.py
from flask import render_template, current_app
from app.email import send_email
def send_congrats_email(user):
send_email('[Congrats] You are registered'),
sender=current_app.config['ADMINS'][0],
recipients=[user.email],
text_body=render_template('email/reset_password.txt',
user=user),
html_body=render_template('email/reset_password.html',
user=user)
在您的 auth/routes.py
中,创建一个用于注册的视图函数:
# app/auth/routes.py
from app.auth.email import send_congrats_email
@bp.route('/register', methods=['GET', 'POST'])
def register():
if current_user.is_authenticated:
return redirect(url_for('main.index'))
form = RegistrationForm()
if form.validate_on_submit():
user = User(username=form.username.data, email=form.email.data)
user.set_password(form.password.data)
db.session.add(user)
db.session.commit()
send_congrats_email(user)
flash('Check your email for our congrats message')
return redirect(url_for('auth.login'))
return render_template('auth/register.html', title='Register',
form=form)
确保在 config
模块中设置您的电子邮件配置:
import os
from dotenv import load_dotenv
basedir = os.path.abspath(os.path.dirname(__file__))
load_dotenv(basedir, '.env')
class Config(object):
# Database configuration
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL?ssl=require') or \
'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
# Form protection
SECRET_KEY = os.environ.get('SECRET_KEY')
# Email configuration
MAIL_SERVER = os.environ.get('MAIL_SERVER')
MAIL_PORT = int(os.environ.get('MAIL_PORT') or 25)
MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS') is not None
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
ADMINS = os.environ.get('ADMINS')
这样,当调用 app/templates/email/
视图函数时,您的电子邮件消息(见 register()
中的模板)将发送给新注册的用户。