跳转到主要内容

Django库,用于将消息内容与传输方法分离

项目描述

django-herald

Latest PyPI version Tests Black Coverage Status

Logo

一个Django消息库,具有以下特性

  • 类似于Django Admin的类声明和注册方法
  • 支持每条消息使用多种传输方式(电子邮件、短信、Slack 等)
  • 基于浏览器的消息预览
  • 维护消息发送尝试的历史记录,可以查看这些消息
  • 按用户禁用通知

支持 Python/Django

我们试图让 herald 支持 django 所支持的所有版本以及它们之间的所有版本。

对于 Python,herald 支持上述 django 版本所支持的 Python 所有版本。

因此,截至 herald v0.3,我们支持 django 3.2 和 4.x+,以及 Python 3.6、3.7、3.8、3.9 和 3.10。

安装

  1. pip install django-herald
  2. heralddjango.contrib.sites 添加到 INSTALLED_APPS
  3. 添加 herald 的 URLS
from django.conf import settings
from django.conf.urls import url, include

urlpatterns = []

if settings.DEBUG:
    urlpatterns = [
        url(r'^herald/', include('herald.urls')),
   ] + urlpatterns

用法

  1. 在任何 django 应用中创建一个 notifications.py 文件。这是你的通知类所在的地方。添加一个类似这样的类
from herald import registry
from herald.base import EmailNotification


class WelcomeEmail(EmailNotification):  # extend from EmailNotification for emails
    template_name = 'welcome_email'  # name of template, without extension
    subject = 'Welcome'  # subject of email

    def __init__(self, user):  # optionally customize the initialization
        self.context = {'user': user}  # set context for the template rendering
        self.to_emails = [user.email]  # set list of emails to send to

    @staticmethod
    def get_demo_args():  # define a static method to return list of args needed to initialize class for testing
        from users.models import User
        return [User.objects.order_by('?')[0]]

registry.register(WelcomeEmail)  # finally, register your notification class

# Alternatively, a class decorator can be used to register the notification:

@registry.register_decorator()
class WelcomeEmail(EmailNotification):
    ...
  1. 使用此文件结构创建用于渲染电子邮件的模板

     templates/
         herald/
             text/
                 welcome_email.txt
             html/
                 welcome_email.html
    
  2. 通过导航到 /herald/ 来测试电子邮件的外观

  3. 在代码的任何需要位置发送电子邮件

     WelcomeEmail(user).send()
    
  4. 在 django 管理员中查看已发送的电子邮件,甚至可以重新发送。

电子邮件选项

可以在电子邮件通知类中设置以下选项。例如

class WelcomeEmail(EmailNotification):
    cc = ['test@example.com']
  • from_email: (str,默认:settings.DEFAULT_FROM_EMAIL)发件人电子邮件地址
  • subject: (str,默认: ) 电子邮件主题
  • to_emails: (List[str],默认:None)要发送到的电子邮件字符串列表
  • bcc: (List[str],默认:None)作为 bcc 发送的电子邮件字符串列表
  • cc: (List[str],默认:None)作为 cc 发送的电子邮件字符串列表
  • headers: (dict,默认:None)传递给 EmailMultiAlternatives 对象的额外标题
  • reply_to: (List[str],默认:None)作为回复-to 发送的电子邮件字符串列表
  • attachments: (list)附件列表。有关更多信息,请参阅下面的“电子邮件附件”

自动删除旧通知

Herald 在发送新通知时可以自动删除旧通知。

要启用此功能,将 HERALD_NOTIFICATION_RETENTION_TIME 设置为 timedelta 实例。

例如

HERALD_NOTIFICATION_RETENTION_TIME = timedelta(weeks=8)

每次发送新通知时,将删除所有超过 8 周的通知。

手动删除旧通知

“delnotifs”命令用于清除通知历史记录。

默认用法将删除今天发送的所有内容

python manage.py delnotifs

但是,您也可以传递 startend 日期的参数。 end 是包括但不限于该日期。

  • 如果只指定 end,则删除所有在结束日期之前发送的内容。
  • 如果只指定 start,则删除自起始日期以来发送的所有内容。
  • 如果同时指定 startend,则删除起始日期和结束日期之间的所有内容,不包括结束日期。
python manage.py delnotifs --start='2016-01-01' --end='2016-01-10'

异步发送电子邮件

如果您要向大量人群发送略有不同的电子邮件,处理时间可能相当长。默认情况下,Django 将同步处理这些操作。为了异步支持,我们推荐使用 django-celery-email。它非常简单易设,并且易于集成:https://github.com/pmclanahan/django-celery-email

herald.contrib.auth

Django 内置支持发送密码重置电子邮件。如果您想使用 herald 发送这些电子邮件,可以使用 herald.contrib.auth 中的通知类。

首先,将 herald.contrib.auth 添加到 INSTALLED_APPS(除了 herald)。

其次,使用 HeraldPasswordResetForm 替换 django 内置的 PasswordResetForm。这一步完全取决于您的项目结构,但本质上只是在密码重置视图中以某种方式更改表单类。

# you may simply just need to override the password reset url like so:
url(r'^password_reset/$', password_reset, name='password_reset', {'password_reset_form': HeraldPasswordResetForm}),

# of if you are using something like django-authtools:
url(r'^password_reset/$', PasswordResetView.as_view(form_class=HeraldPasswordResetForm), name='password_reset'),

# or you may have a customized version of the password reset view:
class MyPasswordResetView(FormView):
    form_class = HeraldPasswordResetForm  # change the form class here

# or, you may have a custom password reset form already. In that case, you will want to extend from the HeraldPasswordResetForm:
class MyPasswordResetForm(HeraldPasswordResetForm):
    ...

# alternatively, you could even just send the notification wherever you wish, seperate from the form:
PasswordResetEmail(some_user).send()

第三,您可能想自定义电子邮件的模板。默认情况下,herald 将使用 django 提供的 registration/password_reset_email.html,用于电子邮件的 html 和纯文本版本。但您可以直接覆盖 herald/html/password_reset.html 和/或 herald/text/password_reset.txt 以满足您的需求。

用户禁用通知

如果您想禁用某些用户的通知,请向 UserNotification 表中添加记录,并将通知添加到 disabled_notifications 多对多表中。

例如

user = User.objects.get(id=user.id)

notification = Notification.objects.get(notification_class=MyNotification.get_class_path())

# disable the notification
user.usernotification.disabled_notifications.add(notification)

默认情况下,通知可以被禁用。您可以在您的通知类中设置 can_disable = False,系统将使用此默认值填充数据库。您的通知类还可以通过在继承的通知类中设置它来覆盖 verbose_name。如下所示

class MyNotification(EmailNotification):
    can_disable = False
    verbose_name = "My Required Notification"

电子邮件附件

要发送附件,将附件列表分配给 EmailNotification 实例的 attachments 属性,或覆盖 get_attachments() 方法。

列表中的每个附件可以是以下之一

  1. 一个包含文件名、原始附件数据和 mime 类型的元组。获取附件数据取决于您。如下所示
raw_data = get_pdf_data()

email.attachments = [
    ('Report.pdf', raw_data, 'application/pdf'),
    ('report.txt', 'text version of report', 'text/plain')
]
email.send()
  1. MIMEBase 对象。请参阅 Django 文档中 EmailMessage 对象/附件部分的附件文档。

  2. django File 对象。

内联附件

有时您想在电子邮件内容中直接嵌入图像。通过为 MIMEImage 分配内容 id 头部来实现,如下所示

email = WelcomeEmail(user)
im = get_thumbnail(image_file.name, '600x600', quality=95)
my_image = MIMEImage(im.read()) # MIMEImage inherits from MIMEBase
my_image.add_header('Content-ID', '<{}>'.format(image_file.name))

您可以在您的 html 电子邮件模板中使用内容 ID (cid) 来引用这些图像,如下所示

<img src="cid:{{image_file.name}}" />

当然,您需要在上面的示例中将 "image_file" 添加到您的模板上下文中。您也可以通过文件操作来完成此操作。在这个示例中,我们覆盖了 EmailNotification 的 get_attachments 方法。

class MyNotification(EmailNotification):
    context = {'hello': 'world'}
    template_name = 'welcome_email'
    to_emails = ['somebody@example.com']
    subject = "My email test"
        
    def get_attachments(self):
        fp = open('python.jpeg', 'rb')
        img = MIMEImage(fp.read())
        img.add_header('Content-ID', '<{}>'.format('python.jpeg'))
        return [
            img,
        ]

在您的模板中,您将这样引用它,并且您不需要向上下文中添加任何内容

    <img src="cid:python.jpeg" />

HTML2Text 支持

Django Herald 可以自动将您的 HTML 电子邮件转换为纯文本。如果您启用此功能,则任何没有纯文本版本的电子邮件将自动转换。

# Install html2text
pip install django-herald[html2text]

在您的 settings.py 文件中

HERALD_HTML2TEXT_ENABLED = True

您可以通过设置配置字典来自定义 HTML2Text 的输出。有关选项,请参阅 HTML2Text 配置

HERALD_HTML2TEXT_CONFIG = {
    # Key / value configuration of html2text 
    'ignore_images': True  # Ignores images in conversion
}
HERALD_RAISE_MISSING_TEMPLATES = True

默认情况下,如果为真(默认值),Herald 将在模板缺失时引发异常。

Twilio

# Install twilio
pip install django-herald[twilio]

您可以在 Twilio 控制台 中检索这些值。一旦检索到必要的 id,您就可以将它们放在 settings.py 中。

作为参考,Twilio 为 Python 提供了一些优秀的教程。请参阅 Twilio Python 教程

# Twilio configurations
# values taken from `twilio console`
TWILIO_ACCOUNT_SID = "your_account_sid"
TWILIO_AUTH_TOKEN = "your_auth_token"
TWILIO_DEFAULT_FROM_NUMBER = "+1234567890"

其他 MIME 附件

您还可以将任何 MIMEBase 对象作为常规附件附加,但您必须添加一个内容处置头,否则它们将不可访问

my_image.add_header('Content-Disposition', 'attachment; filename="python.jpg"')

附件可能导致您的数据库变得非常大,因此您应该确保运行管理命令以清除旧消息的数据库。

运行测试

python runtests.py

项目详情


下载文件

下载您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码分发

django-herald-0.3.0.tar.gz (18.2 kB 查看散列值)

上传时间 源代码

构建分发

django_herald-0.3.0-py2.py3-none-any.whl (23.4 kB 查看散列值)

上传时间 Python 2 Python 3

由以下支持