Django 博客评论系统 (三) : 用邮件通知回复

瞳人


发布于 Oct. 22, 2015, 7:20 p.m.

8 个评论

Django


在前几部分简单介绍了如何添加一个评论系统, 本文将介绍如何发送邮件通知来提醒用户有新的回复.

Django 邮件配置

可以使用 smtp 配置, 或者使用 mailgun api 来设置, 详见之前的 Django 邮件配置博客.

相关代码

其实这个很简单, 就是继承本来 comments 中的 CommentModerator官方代码, 然后覆盖一些我们需要自定义的方法和变量.

重要更新 更新于 2016 年 07 月 29 日,由于 send_mail 会导致 recipient_list 中所有对象全部显示在发送至列表中,这样会将别人的邮件地址暴露给他人,这样不够注重隐私,所以现在使用 send_mass_mail 方法。

blog/models.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from django_comments.moderation import CommentModerator, moderator
class ArticleModerator(CommentModerator):
    email_notification = True
    # 指明博客 Article 模型中作为是否禁止评论的属性
    enable_field = 'enable_comments'

    def email(self, comment, content_object, request):
        """
        Send email notification of a new comment to site staff when email
        notifications have been requested.

        """
        if not self.email_notification:
            return
        # 默认把所有 settings.py 中的 MANAGERS 添加到收件人中
        recipient_list = [manager_tuple[1] for manager_tuple in settings.MANAGERS]
        site = get_current_site(request)
        subject = u'[%s] New comment posted on "%s"' % (site.name, content_object)
        message = render_to_string(
            'comments/comment_notification_email.txt',
            {
                'site' : site,
                'comment': comment,
                'content_object': content_object,
            }
        )
        # Add the users of the parent comments
        # 这里是为了递归向上把该条评论所回复的所有祖先评论的用户都加入到通知列表中
        pp = comment.parent
        while pp:
            mail_addr = pp.user_email
            if not mail_addr and pp.user and pp.user.email:
                mail_addr = pp.user.email
            if mail_addr and not mail_addr in recipient_list:
                recipient_list.append(mail_addr)
            pp = pp.parent
        # 注意!更新于 2016 年 07 月 29 日,由于 send_mail 会导致 recipient_list 中所有对象全部显示在
        # 发送至列表中,这样会将别人的邮件地址暴露给他人,这样不够注重隐私,所以改为 send_mass_mail
        # send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, recipient_list, fail_silently=True)
        data_tuple = (
            (subject, message, settings.DEFAULT_FROM_EMAIL, [recipient, ]) for recipient in recipient_list
        )
        send_mass_mail(data_tuple, fail_silently=True)

moderator.register(Article, ArticleModerator)

settings.py 中添加 MANAGERS:

1
2
3
ADMINS = (
    ('Your Name', 'your_email@example.com'),
)

comments/comment_notification_email.txt:

1
2
3
4
5
6
7
8
9
A comment has been posted on {{ site.name }} {{ content_object }}.
The comment reads as follows:

Comment:
{{ comment.comment }}

----
You have the following options available:
  View comment    -- http://{{ site.domain }}{{ comment.get_absolute_url }}

哎呦, 不错哦!

8 Comments

Jerusalemsbell March 18, 2016, 4:26 p.m. | Reply

你好!偶然看到你的博客有关评论的部分,感觉有收获,特别来感谢。
不过我好像看到了一个bug,分类阅读Django,如果点击下一页的话,url会从category/django 跳转到/page/2是不是后台逻辑错误?

瞳人 March 21, 2016, 2:26 p.m. | Reply

谢谢!我好久没有维护我博客的代码了。。主要是因为我懒。。
确实是我代码写错了。。
我在博客类别中的 template 的分页部分是直接从我首页的 template 中拷贝过去的。
当时忘记改了,所以就跳到主页的分页中去了。
非常感谢指出来!

dlwxxxdlw Oct. 12, 2016, 4:47 p.m. | Reply

TypeError at /sblog/blog/3/
'MyCommentForm' object is not iterable
Request Method: GET
Request URL: http://localhost:8000/sblog/blog/3/
Django Version: 1.9.7
Exception Type: TypeError
Exception Value:
'MyCommentForm' object is not iterable
Exception Location: /Library/Python/2.7/site-packages/django/template/defaulttags.py in render, line 167
Python Executable: /usr/bin/python
Python Version: 2.7.10
Python Path:
['/Users/dlw/Documents/DLW/Django/blogDemo',
'/Library/Python/2.7/site-packages/robot-20071211-py2.7.egg',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages',
'/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload',
'/Users/dlw/Library/Python/2.7/lib/python/site-packages',
'/usr/local/lib/python2.7/site-packages',
'/usr/local/lib/python2.7/site-packages/wx-3.0-osx_cocoa',
'/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC',
'/Library/Python/2.7/site-packages',
'/Library/Python/2.7/site-packages/wx-2.9.5-osx_cocoa']
Server time: Wed, 12 Oct 2016 16:10:10 +0800

dlwxxxdlw Oct. 12, 2016, 4:49 p.m. | Reply

跟着上一篇教程做的,在上一篇评论结果报错,只好跑到这来评论
```python
from crispy_forms.helper import FormHelper
from threadedcomments.forms import ThreadedComment as base_class

class MyCommentForm(base_class):

helper = FormHelper()
helper.form_tag = False
```

dlwxxxdlw Oct. 13, 2016, 3:30 p.m. | Reply

找到错误原因了:from threadedcomments.forms import ThreadedComment as base_class 这里错了,应该是:ThreadedCommentForm。谢谢博主的教程,获益匪浅!

瞳人 Oct. 15, 2016, 7:21 p.m. | Reply

不用谢啦!解决问题就好啦!
不好意思哦,我最近在考试,所以现在才回复你。

啊啊 Jan. 18, 2017, 2:23 p.m. | Reply

dsafdsfas

test April 7, 2017, 2:34 p.m. | Reply

12341234


Leave a Comment:

博客搜索

友情链接

公告

本博客代码已经公布在 Github 上,欢迎交流指正。

QQ 邮箱对 mailgun 不太友好, 所以使用 QQ 邮箱的评论, 可能会无法及时收到邮件。我会尽快寻找其他解决方案的。

本人现在独自使用 linode vps, 20 美元/月, 感觉压力大, 如果有意一起合租, 可以联系我. 在我的任意一篇文章下面留言即可. 关于使用方式, 现在倾向于使用 docker.