django - 在 Wagtail 中发布新博文时向订阅者发送电子邮件通知

标签 django wagtail email-notifications

我正在将现有的 Django 项目转换为 Wagtail。我遇到的一个问题是电子邮件通知。在 Django 项目中,我可以让人们订阅博客,每当发布新帖子时,作者可以手动向管理员中的所有订阅者发送通知。但是,我不确定如何在 Wagtail 中完成此操作。

我已经阅读了有关 page_published 信号 ( https://docs.wagtail.io/en/stable/reference/signals.html#page-published ) 的文档,但是,我不确定如何将我当前的代码集成到其中。此外,我更希望作者手动发送通知,因为作者不想在每次编辑和随后发布博文时都向订阅者发送电子邮件。

作为引用,我目前的 Django 应用程序代码如下(只有博客应用程序在普通 Django 中才有效;因为博客模型现在在 Wagtail 应用程序中,当前代码不再有效)。

模型.py

class Post(models.Model):
    """Fields removed here for brevity."""
    ...
    def send(self, request):
        subscribers = Subscriber.objects.filter(confirmed=True)
        sg = SendGridAPIClient(settings.SENDGRID_API_KEY)
        for sub in subscribers:
            message = Mail(
                    from_email=settings.FROM_EMAIL,
                    to_emails=sub.email,
                    subject="New blog post!",
                    html_content=(               #Abbreviated content here for brevity
                        'Click the following link to read the new post:' \
                        '<a href="{}/{}/">{}</a>'\
                        'Or, you can copy and paste the following url into your browser:' \
                        '{}/{}'\
                        '<hr>If you no longer wish to receive our blog updates, you can ' \
                        '<a href="{}/?email={}&conf_num={}">unsubscribe</a>.').format(
                            request.build_absolute_uri('/post'),
                            self.slug,
                            self.title,
                            request.build_absolute_uri('/post'),
                            self.slug,
                            request.build_absolute_uri('/delete'),
                            sub.email,
                            sub.conf_num
                        )
                    )
            sg.send(message)

admin.py

def send_notification(modeladmin, request, queryset):
    for post in queryset:
        post.send(request)

send_notification.short_description = "Send selected Post(s) to all subscribers"

@admin.register(Post)
class PostAdmin(SummernoteModelAdmin):
    ...
    actions = [send_notification]

如有任何建议或反馈,我们将不胜感激!提前致谢!

编辑 1

我从 Wagtail Slack 那里得到了使用 register_page_action_menu_item Hook ( https://docs.wagtail.io/en/stable/reference/hooks.html?highlight=hooks#register-page-action-menu-item ) 的建议。我在 Wagtail 的页面编辑器上成功实现了操作菜单项,但是我无法执行我的电子邮件方法(可能是因为我不知道如何正确使用 Hook )。下面是我的 wagtail_hooks.py 文件中的代码。

from wagtail.admin.action_menu import ActionMenuItem
from wagtail.core import hooks

from .models import Subscriber
from django.conf import settings
from django.core.mail import send_mail
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import (Mail, Attachment, FileContent, FileName, FileType, Disposition)

class NotificationMenuItem(ActionMenuItem):
    name = 'email-notification'
    label = "Notify Subscribers of New Post"

    def send(self, request):
    """Used the same def send() method here from my models.py above"""

@hooks.register('register_page_action_menu_item')
def register_notification_menu_item():
    return NotificationMenuItem(order=100)

如果有人对如何修复它以使其执行有任何建议,请告诉我!

编辑 2

更多问题! (虽然我觉得我越来越近了。)

wagtail_hooks.py 修改为以下内容,我可以发送电子邮件,但它发生在页面加载。所以每次我在编辑器中加载博客文章时,它都会发送一封电子邮件。单击我创建的操作菜单项会触发页面重新加载,然后发送另一封电子邮件(因此我认为我的操作菜单项在单击时实际上并没有起作用)。

另一个问题:因为我将 send() 方法移到了 NotificationMenuItem 类中,所以我无法在电子邮件。

wagtail_hooks.py

class NotificationMenuItem(ActionMenuItem):
    name = 'email-notification'
    label = "Notify Subscribers of New Post"

    def send(self, request):
    """Used the same def send() method here from my models.py above"""

    def get_url(self, request, context):
        self.send(request)

编辑 3

尽管模型是 Wagtail 模型,但我设法让通知系统在常规 Django 管理中工作。虽然这会将当前网站的功能转移到新的 wagtail 网站,但我仍然无法解决在编辑 2 下提出的最新问题。

这是管理员中的新代码:

def send_notification(modeladmin, request, queryset):
    for post in queryset:
        post.send(request)

send_notification.short_description = "Send selected Post(s) to all subscribers"

class BlogPageAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'body')
    search_fields = ['title', 'body']
    actions = [send_notification]
admin.site.register(BlogPage, BlogPageAdmin)

最佳答案

最好您需要使用 post_save 信号。

@receiver(post_save, sender=BlogPost)
def send_mail_to_subs(sender, instance, created, **kwargs):
    current_site = Site.objects.get_current()
    domain = current_site.domain
    if created:
        for subs in instance.author.subscribed.all():
            send_mail(
                f'New Post from {instance.author}',
                f'Title: {instance.post_title}\nContent: {instance.post_content}\nDate Created: {instance.created}\nUrl: {domain}',
                'youremail',
                [subs.email],
        )

良好的编码。

关于django - 在 Wagtail 中发布新博文时向订阅者发送电子邮件通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62760530/

相关文章:

python - 如何不可知论地链接来自另一个 Django 模型的任何对象/模型?

python - 我正在学习 Conda environment.yml,我不确定如何让 Conda 找到特定版本的依赖项

python - 当我不使用 "127.0.0.1:8000"时找不到 django wagtail 页面

php - WooCommerce 电子邮件通知 : different email recipient for different cities

wordpress - 保存订单表后添加的自定义行中的值并将其显示在 WooCommerce 订单和电子邮件中

php - 删除 woocommerce 电子邮件通知中的产品下载部分

Django REST Framework - 对嵌套序列化程序的查询限制?

python - Django Rest Framework - 如何限制使用 Geolocation 返回的结果?

python - Django 嵌套序列化器未序列化内部模型

python - 在继承类中扩展 wagtail Streamfields