跳转到主要内容

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

项目描述

django-heralder

Latest PyPI version Tests Black codecov

Logo

一个具有以下功能的Django消息库:

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

历史记录

Django-Heralder是遗留项目Django-Herald的一个分支。

Django-Herald v0.3.0版本与Django-Heralder v0.3.0版本具有相同的特性和功能。Django-Heralder v0.3.0之后的版本将因新增功能和错误修复而有所区别。

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-heralder
  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)要作为密送发送的电子邮件字符串列表
  • cc: (List[str],默认值:None)要作为抄送发送的电子邮件字符串列表
  • headers: (dict,默认值:None)传递给EmailMultiAlternatives对象的额外标题
  • reply_to: (List[str],默认值:None)要作为回复地址发送的电子邮件字符串列表
  • 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,系统将使用此默认值填充数据库。您的Notification类还可以通过在继承的Notification类中设置来覆盖verbose_name。例如:

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

电子邮件附件

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

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

  1. 一个包含文件名、原始附件数据和mimetype的元组。获取附件数据由您决定。例如:
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并为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))

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

<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-heralder[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-heralder[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对象作为常规附件附加,但您必须添加content-disposition头,否则它们将不可访问。

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

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

运行测试

python runtests.py

项目详情


下载文件

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

源分布

django-heralder-0.3.0.tar.gz (18.4 kB 查看哈希值)

上传时间:

构建分布

django_heralder-0.3.0-py2.py3-none-any.whl (23.6 kB 查看哈希值)

上传时间: Python 2 Python 3

由 ... 支持