电子邮件支持

因为博客要支持评论,所以我们需要在文章有了新评论后发邮件通知管理员。而且,当管理员回复了读者的评论后,也需要发送邮件提醒读者。

为了方便读者使用示例程序,personalBlog中仍然使用Flask-Mail来发送邮件。读者在运行程序前需要在项目根目录内创建.env文件写入对应的环境变量,以便让发信功能正常工作。

因为邮件的内容很简单,我们将直接在发信函数中写出正文内容,这里只提供了HTML正文。我们有两个需要使用电子邮件的场景:

1、当文章有新评论时,发送邮件给管理员;

2、当某个评论被回复时,发送邮件给被回复用户。

为了方便使用,我们在emails.py中分别为这两个使用场景创建了特定的发信函数,可以直接在视图函数中调用 。这些函数内部则通过我们创建的通用发信函数send_email()来发送邮件,如下所示 :

personalBlog/emails.py: 提醒邮件函数

from flask import url_for

def send_mail(subject, to, html):
pass def send_new_comment_email(post):
# blog.show_post是blog蓝本下的show_post视图函数
post_url = url_for('blog.show_post', post_id = post.id, _external = True) + '#comments'
send_mail(subject = 'New comment', to = current_app.config['BLUEBLOG_ADMIN_EMAIL'],
html = '<p>New comment in post <i>%s</i>, click the link below to check:</p>'
'<p><a href="%s">%s</a></p>'
'<p><small style = "color:#868e96">Do not reply this email.</small></p>'
% (post.title, post_url, post_url)) def send_new_reply_email(comment):
post_url = url_for('blog.show_post', post_id = comment.post_id, _external = True) + '#comments'
send_mail(subject = 'New reply', to = comment.email,
html = '<p>New reply for the comment you left in post <i>%s</i>, click the link below to check: </p>'
'<p><a href="%s">%s</a></p>'
'<p><small style="color: #868e96">Do not reply this email.</small></p>'
% (comment.post.title, post_url, post_url))

send_new_comment_email()函数用来发送新评论提醒邮件。 我们通过将url_for()函数的_external参数设为True来构建外部链接。链接尾部的#comments是用来跳转到页面评论部分的URL片段(URL fragment),comments是评论部分div元素的id值。这个函数接收表示文章的post对象作为参数,从而生成文章正文的标题和链接。

URL片段又称片段标识符(fragment identifier),是URL中用来表示页面中资源位置的短字符,以#开头,对于HTML页面来说,一个典型的示例是文章页面的评论区。假设评论区的div元素id为comment,如果我们访问http://example.com/post/7#comment,页面加载完成后将会直接跳到评论部分。

send_new_reply_email()函数则用来发送新回复提醒邮件。这个发信函数接收comment对象作为参数,用来构建邮件正文,所属文章的主键值通过comment.post_id属性获取,标题则通过comment.post.titlle属性获取。

在personalBlog源码中,我们没有使用异步的方式发送邮件,如果你希望编写一个异步发送邮件的通用发信函数send_mail(),和之前介绍的基本相同,如下所示

from threading import Thread
from flask import current_app
from flask_mail import Message from personalBlog.extensions import mail def _send_async_mail(app, message):
with app.app_context():
mail.send(message) def send_async_mail(subjecct, to, html):
app = current_app._get_current_object() # 获取被代理的真实对象
message = Message(subjecct, recipients=[to], html = html)
thr = Thread(target = _send_async_mail, args = [app, message])
thr.start()
return thr

需要注意,因为我们的程序是通过工厂函数创建的,所以实例化Thread类时,我们使用代理对象current_app作为args参数列表中app的值。另外,因为在新建线程时需要真正的程序对象来创建上下文,所以不能直接传入current_app,而是传入current_app调用_get_current_app()方法获取的被代理的程序实例。

flask实战-个人博客-电子邮件支持的更多相关文章

  1. flask实战-个人博客-虚拟环境、项目结构

    个人博客 博客是典型的CMS(Content Management system,内容管理系统),通常由两部分组成:一部分是博客前台,用来展示开放给所有用户的博客内容:另一部分是博客后台,这部分内容仅 ...

  2. flask实战-个人博客-编写博客前台

    编写博客前台 博客前台需要开放给所有用户,这里包括显示文章列表.博客信息.文章内容和评论等功能功能. 分页显示文章列表 为了在主页显示文章列表,我们要先在渲染主页模板的index视图的数据库中获取所有 ...

  3. flask实战-个人博客-模板 --

    模板 personalBlog采用典型的博客布局,左侧三分之二为主体,显示文章列表.正文:右侧三分之一为边栏,显示分为类列表.社交链接等.现在的工作是将HTML文件加工为模板,并创建对应的表单类,在模 ...

  4. flask实战-个人博客-数据库-生成虚拟数据 --

    3.生成虚拟数据 为了方便编写程序前台和后台功能,我们在创建数据库模型后就编写生成虚拟数据的函数. 1)管理员 用于生成虚拟管理员信息的fake_admin()函数如下所示: personalBlog ...

  5. flask实战-个人博客-程序骨架、创建数据库模型、临接列表关系 --

    编写程序骨架 personalBlog的功能主要分为三部分:博客前台.用户认证.博客后台,其中包含的功能点如下图所示: 数据库 personalBlog一共需要使用四张表,分别存储管理员(Admin) ...

  6. flask实战-个人博客-使用蓝本模块化程序

    使用蓝本模块化程序 实例化flask提供的blueprint类就创建一个蓝本实例.像程序实例一样,我们可以为蓝本实例注册路由.错误处理函数.上下文处理函数,请求处理函数,甚至是单独的静态文件文件夹和模 ...

  7. flask实战-个人博客-表单

    表单 下面我们来编写所有表单类,personalBlog中主要包含下面这些表单: 登录表单: 文章表单: 评论表单: 博客设置表单: 这里仅介绍登录表单.文章表单.分类表单和评论表单,其他的表单在实现 ...

  8. flask实战-个人博客-使用工厂函数创建程序实例 --

    使用工厂函数创建程序实例 使用蓝本还有一个重要的好处,那就是允许使用工厂函数来创建程序实例.在OOP(Object-Oriented Programming,面向对象编程)中,工厂(factory)是 ...

  9. flask实战-个人博客-使用类组织配置

    使用类组织配置 在实际需求中,我们往往需要不同的配置组合.例如,开发用的配置,测试用的配置,生产环境用的配置.为了能方便地在这些配置中切换,你可以把配置文件升级为包,然后为这些使用场景分别创建不同的配 ...

随机推荐

  1. [LeetCode] 370. Range Addition 范围相加

    Assume you have an array of length n initialized with all 0's and are given k update operations. Eac ...

  2. C语言实现五子棋

    可以称得上史上最简单的五子棋版本了. 可以使用curses库来改进页面和下棋方式. 并且对于输入的坐标没有进行鉴别,如果输入的坐标超过棋盘大小,就会段错误退出. 我改进了一点,但是还是没有完全避免这个 ...

  3. Npcap:Nmap项目里一个为Windows而生的嗅探库 Npcap: Nmap Project's packet sniffing library for Windows

    如果有人知道Npcap与libpcap对应的头文件列表,请告诉我,非常感谢 Introduction介绍 This Manual describes the programming interface ...

  4. 热情组——项目冲刺 Day4

    项目相关 作业相关 具体描述 班级 班级链接 作业要求 链接地址 团队名称 热情组 作业目标 实现软件制作,以及在福大的传播 Github链接 链接地址 SCRUM部分: 成员昵称 昨日目标 开始时间 ...

  5. oracle--介质恢复和实例恢复的基本概念

    1.概念 REDO LOG是Oracle为确保已经提交的事务不会丢失而建立的一个机制.实际上REDO LOG的存在是为两种场景准备的,一种我们称之为实例恢复(INSTANCE RECOVERY),一种 ...

  6. JAVA基础系列:Arrays.binarySearch二分查找

    首先,binarySearch方法为二分法查找,所以数组必须是有序的或者是用sort()方法排序之后的 1)  binarySearch(Object[] a, Object key) a: 要搜索的 ...

  7. ORA-12528: TNS:listener: all appropriate instances are blocking new connections

    Oracle问题:ORA-12528: TNS: 监听程序: 所有适用例程都无法建立新连接 问题原始描述: ORA-12528: TNS:listener: all appropriate insta ...

  8. IDEA 常用命令

    1.快捷键 Alt + Enter 导入包,自动修正代码 Ctrl + Y 删除光标所在行 Ctrl + D 复制光标所在行,插入光标位置下面 Ctrl + Alt + L 格式化代码 Ctrl + ...

  9. Java 中的"+"号(加法和连接)

    Java 中的"+"号(加法和连接) public class Test { public static void main(String[] args) { System.out ...

  10. Android模拟器太慢怎么办?使用微软的VS模拟器

    开发过android的人都知道,android模拟器非常的慢,推荐使用微软的VS模拟器. (1)到 https://visualstudio.microsoft.com/zh-hans/vs/msft ...