首頁 >後端開發 >Python教學 >在 Django 中建立靈活的通知系統:綜合指南

在 Django 中建立靈活的通知系統:綜合指南

Patricia Arquette
Patricia Arquette原創
2024-12-01 15:43:09904瀏覽

Building a Flexible Notification System in Django: A Comprehensive Guide

通知是任何現代 Web 應用程式的關鍵組成部分,可確保使用者了解情況並參與其中。實施良好的通知系統可以處理多個管道,例如應用程式內警報、電子郵件和短信,同時動態自訂內容以實現無縫的用戶體驗。在本指南中,我們將引導您在 Django 中建立一個強大的、可擴展的通知系統。


系統功能

我們的通知系統旨在提供:

  1. 支援多管道:透過應用程式內提醒、電子郵件或簡訊發送通知。
  2. 動態內容個人化:帶有佔位符的模板,用於產生個人化訊息。
  3. 基於事件的觸發器:根據特定係統或使用者事件觸發通知。
  4. 狀態追蹤:監控電子郵件和簡訊通知的傳送狀態。
  5. 管理和系統整合:通知可以由管理員或系統事件觸發。

定義模型

1.通知範本

範本是我們系統的支柱,儲存可重複使用的通知內容。

from django.db import models

class ChannelType(models.TextChoices):
    APP = 'APP', 'In-App Notification'
    SMS = 'SMS', 'SMS'
    EMAIL = 'EMAIL', 'Email'


class TriggeredByType(models.TextChoices):
    SYSTEM = 'SYSTEM', 'System Notification'
    ADMIN = 'ADMIN', 'Admin Notification'


class TriggerEvent(models.TextChoices):
    ENROLLMENT = 'ENROLLMENT', 'Enrollment'
    ANNOUNCEMENT = 'ANNOUNCEMENT', 'Announcement'
    PROMOTIONAL = 'PROMOTIONAL', 'Promotional'
    RESET_PASSWORD = 'RESET_PASSWORD', 'Reset Password'

class NotificationTemplate(models.Model):
    title = models.CharField(max_length=255)
    template = models.TextField(help_text='Use placeholders like {{username}} for personalization.')
    channel = models.CharField(max_length=20, choices=ChannelType.choices, default=ChannelType.APP)
    triggered_by = models.CharField(max_length=20, choices=TriggeredByType.choices, default=TriggeredByType.SYSTEM)
    trigger_event = models.CharField(max_length=50, choices=TriggerEvent.choices, help_text='Event that triggers this template.')
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

主要特點:

  • 模板:帶有動態值佔位符的文本,例如 {{username}}.
  • 頻道:指定是電子郵件、簡訊或應用程式內通知。
  • trigger_event:將範本與特定事件關聯。

2.一般通知

通知模型將模板連結到使用者並儲存任何動態負載以進行個人化。

class Notification(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="notifications")
    content = models.ForeignKey(NotificationTemplate, on_delete=models.CASCADE, related_name="notifications")
    payload = models.JSONField(default=dict, help_text="Data to replace template placeholders.")
    is_read = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

3.特定於渠道的模型

為了獨特地處理電子郵件和短信,我們定義了特定的模型。

電子郵件通知

此模型管理特定於電子郵件的數據,例如動態訊息產生和傳遞追蹤。

class StatusType(models.TextChoices):
    PENDING = 'PENDING', 'Pending'
    SUCCESS = 'SUCCESS', 'Success'
    FAILED = 'FAILED', 'Failed'

class EmailNotification(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='email_notifications')
    content = models.ForeignKey(NotificationTemplate, on_delete=models.CASCADE, related_name='email_notifications')
    payload = models.JSONField(default=dict)
    status = models.CharField(max_length=20, choices=StatusType.choices, default=StatusType.PENDING)
    status_reason = models.TextField(null=True)

    @property
    def email_content(self):
        """
        Populate the template with dynamic data from the payload.
        """
        content = self.content.template
        for key, value in self.payload.items():
            content = re.sub(
                rf"{{{{\s*{key}\s*}}}}",
                str(value),
                content,
            )
        return content

簡訊通知

與電子郵件通知類似,這裡實現了簡訊特定邏輯。

class SMSNotification(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sms_notifications')
    content = models.ForeignKey(NotificationTemplate, on_delete=models.CASCADE, related_name='sms_notifications')
    payload = models.JSONField(default=dict)
    status = models.CharField(max_length=20, choices=StatusType.choices, default=StatusType.PENDING)
    status_reason = models.TextField(null=True)

    @property
    def sms_content(self):
        """
        Populate the template with dynamic data from the payload.
        """
        content = self.content.template
        for key, value in self.payload.items():
            content = re.sub(
                rf"{{{{\s*{key}\s*}}}}",
                str(value),
                content,
            )
        return content

管理整合

為了更輕鬆地管理通知,我們在 Django 管理面板中註冊模型。

from django.contrib import admin
from notifier.models import NotificationTemplate

@admin.register(NotificationTemplate)
class NotificationTemplateAdmin(admin.ModelAdmin):
    list_display = ['title', 'channel', 'triggered_by', 'trigger_event', 'is_active']
    list_filter = ['channel', 'triggered_by', 'is_active']
    search_fields = ['title', 'trigger_event']

通知服務

我們將實作一個服務層來管理透過各種管道發送通知。

策略模式

使用策略模式,我們將為每個通知頻道定義類別。

from django.db import models

class ChannelType(models.TextChoices):
    APP = 'APP', 'In-App Notification'
    SMS = 'SMS', 'SMS'
    EMAIL = 'EMAIL', 'Email'


class TriggeredByType(models.TextChoices):
    SYSTEM = 'SYSTEM', 'System Notification'
    ADMIN = 'ADMIN', 'Admin Notification'


class TriggerEvent(models.TextChoices):
    ENROLLMENT = 'ENROLLMENT', 'Enrollment'
    ANNOUNCEMENT = 'ANNOUNCEMENT', 'Announcement'
    PROMOTIONAL = 'PROMOTIONAL', 'Promotional'
    RESET_PASSWORD = 'RESET_PASSWORD', 'Reset Password'

class NotificationTemplate(models.Model):
    title = models.CharField(max_length=255)
    template = models.TextField(help_text='Use placeholders like {{username}} for personalization.')
    channel = models.CharField(max_length=20, choices=ChannelType.choices, default=ChannelType.APP)
    triggered_by = models.CharField(max_length=20, choices=TriggeredByType.choices, default=TriggeredByType.SYSTEM)
    trigger_event = models.CharField(max_length=50, choices=TriggerEvent.choices, help_text='Event that triggers this template.')
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

通知服務

該服務將所有內容連結在一起,根據通知管道選擇適當的策略。

class Notification(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="notifications")
    content = models.ForeignKey(NotificationTemplate, on_delete=models.CASCADE, related_name="notifications")
    payload = models.JSONField(default=dict, help_text="Data to replace template placeholders.")
    is_read = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

使用範例

以下是如何使用通知服務:

class StatusType(models.TextChoices):
    PENDING = 'PENDING', 'Pending'
    SUCCESS = 'SUCCESS', 'Success'
    FAILED = 'FAILED', 'Failed'

class EmailNotification(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='email_notifications')
    content = models.ForeignKey(NotificationTemplate, on_delete=models.CASCADE, related_name='email_notifications')
    payload = models.JSONField(default=dict)
    status = models.CharField(max_length=20, choices=StatusType.choices, default=StatusType.PENDING)
    status_reason = models.TextField(null=True)

    @property
    def email_content(self):
        """
        Populate the template with dynamic data from the payload.
        """
        content = self.content.template
        for key, value in self.payload.items():
            content = re.sub(
                rf"{{{{\s*{key}\s*}}}}",
                str(value),
                content,
            )
        return content

如果您發現本指南很有幫助且富有洞察力,請不要忘記點讚並關注以獲取更多此類內容。您的支持激勵我分享更多實用的實現和深入的教學。讓我們繼續一起建立令人驚嘆的應用程式!

以上是在 Django 中建立靈活的通知系統:綜合指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn