A flexible, multi-channel notification system for Django applications with built-in support for email digests, user preferences, and extensible delivery channels.
- Multi-channel delivery: Send notifications through multiple channels (website, email, and custom channels)
- Flexible delivery frequencies: Support for real-time and digest delivery (daily, or custom schedules)
- Notification grouping: Prevent repeated notifications by grouping notifications based on your own custom logic
- User preferences: Fine-grained control over notification types and delivery channels
- Extensible architecture: Easy to add custom notification types, channels, and frequencies
- Generic relations: Link notifications to any Django model
- Template support: Customizable email templates for each notification type
- Developer friendly: Simple API for sending notifications with automatic channel routing
- Full type hints: Complete type annotations for better IDE support and type checking
- Python >= 3.10
- Django >= 4.2.0
django.contrib.contenttypesmust be inINSTALLED_APPS
All instruction in this document use uv, but of course pip or Poetry will also work just fine.
uv add django-generic-notificationsAdd to your INSTALLED_APPS:
INSTALLED_APPS = [
...
"django.contrib.contenttypes", # Required dependency
"generic_notifications",
...
]Run migrations:
uv run ./manage.py migrate generic_notificationsConfigure the base URL for generating absolute URLs in email notifications:
# With protocol (recommended)
NOTIFICATION_BASE_URL = "https://www.example.com"
NOTIFICATION_BASE_URL = "http://localhost:8000"
# Without protocol (auto-detects based on DEBUG setting)
NOTIFICATION_BASE_URL = "www.example.com"Protocol handling: If you omit the protocol, it's automatically added:
https://in production (DEBUG = False)http://in development (DEBUG = True)
Fallback order if NOTIFICATION_BASE_URL is not set:
BASE_URLsettingSITE_URLsetting- Django Sites framework (if
django.contrib.sitesis installed) - URLs remain relative if no base URL is found (not ideal in emails!)
# myapp/notifications.py
from generic_notifications.types import NotificationType, register
@register
class CommentNotification(NotificationType):
key = "comment"
name = "Comment Notifications"
description = "When someone comments on your posts"from generic_notifications import send_notification
from myapp.notifications import CommentNotification
# Send a notification (only `recipient` and `notification_type` are required)
notification = send_notification(
recipient=post.author,
notification_type=CommentNotification,
actor=comment.user,
target=post,
subject=f"{comment.user.get_full_name()} commented on your post",
text=f"{comment.user.get_full_name()} left a comment: {comment.text[:100]}",
url=f"/posts/{post.id}#comment-{comment.id}",
)from generic_notifications.channels import WebsiteChannel
from generic_notifications.models import Notification
from generic_notifications.lib import get_unread_count, get_notifications, mark_notifications_as_read
# Get unread count for a user
unread_count = get_unread_count(user=user, channel=WebsiteChannel)
# Get unread notifications for a user
unread_notifications = get_notifications(user=user, channel=WebsiteChannel, unread_only=True)
# Get notifications by channel
website_notifications = Notification.objects.prefetch().for_channel(WebsiteChannel)
# Mark as read
notification = website_notifications.first()
notification.mark_as_read()
# Mark all as read
mark_notifications_as_read(user=user)Create a cron job to send daily digests:
# Send daily digests at 9 AM
0 9 * * * cd /path/to/project && uv run ./manage.py send_notification_digests --frequency dailyIf you already have a way to run scheduled jobs in your Django app and don't want to start a management command via a cron job, you can call the send_notification_digests function directly:
from generic_notifications.digest import send_notification_digests
from generic_notifications.frequencies import DailyFrequency
send_notification_digests(frequency=DailyFrequency, dry_run=False)An example app is provided, which shows how to create a custom notification type, how to send a notification, it has a nice looking notification center with unread notifications as well as an archive of all read notifications, plus a settings view where you can manage notification preferences.
cd example
uv run ./manage.py migrate
uv run ./manage.py runserverThen open http://127.0.0.1:8000/.
While the library doesn't register admin classes by default, the example app includes admin configuration that you can copy into your project for debugging and monitoring purposes.
- Migrate to a newer version of this library
- Customization: custom channels, frequencies, and email templates
- Performance considerations and tips
- Notification grouping: prevent notification spam by grouping similar notifications together
- Supporting multilingual notifications
- User preferences: how to manage user preferences
- Development: workflows for working on this library
MIT License - see LICENSE file for details.