赵走x博客
网站访问量:151531
首页
书籍
软件
工具
古诗词
搜索
登录
Flask 实战:41、电子邮件进阶实践
Flask 实战:40、使用事务邮件服务SendGird
Flask 实战:39、使用Flask-Mail发送电子邮件
Flask 实战:38、数据库进阶实践
Flask 实战:37、更新数据库表
Flask 实战:36、定义关系
Flask 实战:35、在视图函数里操作数据库
Flask 实战:34、数据库操作:CRUD
Flask 实战:33、使用Flask-SQLAlchemy管理数据库
Flask 实战:32、ORM魔法
Flask 实战:31、数据库的分类
Flask 实战:30、单个页面多个表单
Flask 实战:29、单个表单多个提交按钮
Flask 实战:28、使用Flask-CKEditor集成富文本编辑器
Flask 实战:27、多文件上传
Flask 实战:26、文件上传
Flask 实战:25、自定义验证器
Flask 实战:24、使用宏渲染表单
Flask 实战:23、设置错误消息语言
Flask 实战:22、处理表单数据
Flask 实战:21、使用Flask-WTF处理表单
Flask 实战:20、HTML表单
Flask 实战:19、模板进阶实践
Flask 实战:18、模板结构组织
Flask 实战:17、模板辅助工具
Flask 实战:16、模板基本用法
Flask 实战:15、HTTP进阶实践
Flask 实战:14、Flask上下文
Flask 实战:13、HTTP响应
Flask 实战:12、HTTP请求
Flask 实战:11、请求响应循环
Flask 实战:10、Flask与MVC架构
Flask 实战:9、模板与静态文件
Flask 实战:8、Flask命令
Flask 实战:7、URL与端点
Flask 实战:6、项目配置
Flask 实战:5、Flask扩展
Flask 实战:4、Python Shell
Flask 实战:3、启动开发服务器
Flask 实战:2、Hello,Flask!
Flask 实战:1、初识Flask
Flask 实战:39、使用Flask-Mail发送电子邮件
资源编号:75890
Python Web
Flask Web开发实战:入门、进阶与原理解析
热度:122
在Web程序中,经常会需要发送电子邮件。比如,在用户注册账户时发送确认邮件;定期向用户发送热门内容或是促销信息等等。在Web程序中发送邮件并不像想象中那么复杂,借助扩展Flask-Mail或是第三方邮件服务,只需几行代码就可以发送电子邮件。
在Web程序中,经常会需要发送电子邮件。比如,在用户注册账户时发送确认邮件;定期向用户发送热门内容或是促销信息等等。在Web程序中发送邮件并不像想象中那么复杂,借助扩展Flask-Mail或是第三方邮件服务,只需几行代码就可以发送电子邮件。 为了演示发信过程,我们会使用一封示例邮件,邮件仅包含几个必要的字段,如表6-1所示。  表6-1 示例邮件信息 标准的收信方和发信方字符串由姓名和邮箱地址两部分组成,二者由空格相隔,比如“姓名
”。字符串中的姓名是可选的,收信方一般可以不写姓名,这时可以直接写出邮箱地址,比如“hello@example.com”。 本章新涉及的Python库如下所示: ·Flask-Mail(0.9.1) ·主页:[https://github.com/mattupstate/flask-mail](https://github.com/mattupstate/flask-mail) ·文档:[https://pythonhosted.org/Flask-Mail/](https://pythonhosted.org/Flask-Mail/) ·SendGrid-Python(5.3.0) ·主页:[https://github.com/sendgrid/sendgrid-python](https://github.com/sendgrid/sendgrid-python) ·文档:[https://github.com/sendgrid/sendgrid-python/blob/master/USAGE.md](https://github.com/sendgrid/sendgrid-python/blob/master/USAGE.md) 扩展Flask-Mail包装了Python标准库中的smtplib包,简化了在Flask程序中发送电子邮件的过程。我们使用Pipenv安装Flask-Mail: ``` $ pipenv install flask-mail ``` 和其他扩展类似,我们实例化Flask-Mail提供的Mail类并传入程序实例以完成初始化,如下所示: ``` from flask_mail import Mail app = Flask(__name__) ... mail = Mail(app) ``` # 1、配置Flask-Mail Flask-Mail通过连接SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)服务器来发送邮件。因此,在开始发送电子邮件前,我们需要配置SMTP服务器。如果你的电脑上已经设置好了SMTP服务器,那么无须过多的配置即可使用,默认的邮件服务器配置即为localhost,端口为25。在开发和测试阶段,我们可以使用邮件服务提供商的SMTP服务器(比如Gmail),这时我们需要对Flask-Mail进行配置。表6-2列出了Flask-Mail提供的常用配置变量。  表6-2 Flask-Mail的常用配置 对发送的邮件进行加密可以避免邮件在发送过程中被第三方截获和篡改。SSL(Security Socket Layer,安全套接字层)和TLS(Transport Layer Security,传输层安全)是两种常用的电子邮件安全协议。TLS继承了SSL,并在SSL的基础上做了一些改进(换句话说,TLS是后期版本的SSL)。所以,在大多数情况下,名词SSL和TLS可以互换使用。它们通过将MAIL_USE_SSL设置为True开启。STARTTLS是另一种加密方式,它会对不安全的连接进行升级(使用SSL或TLS)。尽管它的名字中包含TLS,但也可能会使用SSL加密。根据加密的方式不同,端口也要相应改变,如下所示: * 1)SSL/TLS加密: ``` MAIL_USE_SSL = True MAIL_PORT = 465 ``` * 2)STARTTLS加密 ``` MAIL_USE_TLS = True MAIL_PORT = 587 ``` > 提示 当不对邮件进行加密时,邮件服务器的端口使用默认的25端口。 常用电子邮箱服务提供商的SMTP配置信息如表6-3所示。  表6-3 常用SMTP服务提供商配置  > 提示 163邮箱的SMTP服务器不支持STARTTLS,你需要使用SSL/TLS加密。具体来说,需要将MAIL_USE_SSL设为True,MAIL_PORT设为465。 要使用这些邮箱服务,你需要访问对应的网站注册一个账户。开启邮箱的SMTP服务和获取授权码等操作均可以在各邮箱主页→设置(→账户)中找到。 >注意 Gmail、Outlook、QQ邮箱等这类服务被称为EPA(Email Service Provider),只适用于个人业务使用,不适合用来发送事务邮件(Transactional Email)。对于需要发送大量邮件的事务性邮件任务,更好的选择则是使用自己配置的SMTP服务器或是使用类似SendGrid、Mailgun的事务邮件服务提供商(Transactional Email Service),后面会具体介绍。 在程序中,随着配置逐渐增多,我们改用app.config对象的update()方法来加载配置,如代码清单所示。 ``` import os from flask import Flask from flask_mail import Mail app = Flask(__name__) app.config.update( ... MAIL_SERVER = os.getenv('MAIL_SERVER') MAIL_PORT = 587 MAIL_USE_TLS = True MAIL_USERNAME = os.getenv('MAIL_USERNAME') MAIL_PASSWORD = os.getenv('MAIL_PASSWORD') MAIL_DEFAULT_SENDER = ('Grey Li', os.getenv('MAIL_USERNAME')) ) mail = Mail(app) ``` > 注意 在实例化Mail类时,Flask-Mail会获取配置以创建一个用于发信的对象,所以确保在实例化Mail类之前加载配置。 在我们的配置中,邮箱账户和密码属于敏感信息,不能直接写在脚本中,所以设置为从系统环境变量中获取。另外,在生产环境中,我们通常会使用不同的邮件服务器地址,所以这里也从环境变量中读取。你可以使用export/set命令设置环境变量,为了方便管理,我们把这些环境变量存储在.env文件中: ``` MAIL_SERVER=smtp.example.com MAIL_USERNAME=yourusername@example.com MAIL_PASSWORD=your_password ``` 默认发信人由一个两元素元组组成,即(姓名,邮箱地址),比如: ``` MAIL_DEFAULT_SENDER = ('Your Name', 'your_name@example.com') ``` 需要注意,使用邮件服务提供商提供的SMTP服务器发信时,发信人字符串中的邮件地址必须和邮箱地址相同。你可以直接使用MAIL_USERNAME的值构建发信人地址: ``` MAIL_DEFAULT_SENDER = ('Your Name', os.getenv('MAIL_USERNAME')) ``` Flask-Mail会把这个元组转换为标准的发信人格式,即Your Name
。你也可以直接以这种方式指定发信人,比如: ``` MAIL_DEFAULT_SENDER = 'Your Name
' ``` 设置默认发信人后,在发信时就可以不用再指定发信人。 # 2、构建邮件数据 下面我们借助Python Shell演示发送邮件的过程。邮件通过从Flask-Mail中导入的Message类表示,而发信功能通过我们在程序包的构造文件中创建的mail对象实现,我们先进行导入: ``` $ flask shell >>> from flask_mail import Message >>> from app import mail ``` 一封邮件至少要包含主题、收件人、正文、发信人这几个元素。发信人(sender)在前面我们已经使用MAIL_DEFAULT_SENDER配置变量指定过了,剩下的分别通过Message类的构造方法中的subject、recipients、body关键字传入参数,其中recipients为一个包含电子邮件地址的列表。 ``` >>> message = Message(subject='Hello, World!', recipients=['Zorn
'], body='Across the Great Wall we can reach every corner in the world.') ``` >提示 和发信人字符串类似,收信人字符串可以为两种形式:'Zorn
'或'zorn@example.com'。 Message类的构造方法支持其他参数来定义邮件首部的其他字段,具体可参考Flask-Mail文档或源码。 # 3、发送邮件 通过对mail对象调用send()方法,传入我们在上面构建的邮件对象即可发送邮件: ``` >>> mail.send(message) ``` 完整的发送示例邮件的代码如下所示: ``` from flask_mail import Message from app import mail ... message = Message(subject='Hello, World!', recipients=['Zorn
'], body='Across the Great Wall we can reach every corner in the world.') mail.send(message) ``` 为了方便重用,我们把这些代码包装成一个通用的发信函数send_mail(),如代码清单6-2所示。 代码清单6-2 app.py:通用发信函数 ``` from flask_mail import Mail, Message ... mail = Mail(app) ... def send_mail(subject, to, body): message = Message(subject, recipients=[to], body=body) mail.send(message) ``` 假设我们的程序是一个周刊订阅程序,当用户在表单中填写了正确的Email地址时,我们就发送一封邮件来通知用户订阅成功。通过在index视图中调用send_email()即可发送邮件,如代码清单6-3所示。 代码清单6-3 在视图函数中发送邮件 ``` @app.route('/subscribe', methods=['GET', 'POST']) def subscribe(): form = SubscribeForm() if form.validate_on_submit(): email = form.email.data flash('Welcome on board!') send_email('Subscribe Success!', email, 'Hello, thank you for subscribing Flask Weekly!') return redirect(url_for('idnex')) return render_template('index.html', form=form) ```