Skip to main content

Advanced notifications for Django

Project description

django-whistle

Django Whistle is a Django app that provides a flexible, multi-channel notification system. Supports web (in-app), email, and push (FCM) channels with user preferences and background job processing.

Installation

pip install django-whistle

Add to your INSTALLED_APPS:

INSTALLED_APPS = [
    # ...
    'whistle',
    'fcm_django',  # only if using push notifications
]

Run migrations:

python manage.py migrate whistle

Configuration

Events and Channels

Define notification events and enable channels in your settings.py:

from django.utils.translation import gettext_lazy as _

WHISTLE_CHANNELS = ['web', 'push', 'email']
WHISTLE_NOTIFICATION_EVENTS = (
    ('ORDER_PLACED', _('%(actor)s placed order %(object)s')),
    ('ORDER_SHIPPED', _('Your order %(object)s has been shipped')),
)

Template variables: %(actor)s, %(object)s, %(target)s

User Model Integration

Add the mixin to your User model for notification preferences and unread counts:

from whistle.mixins import UserNotificationsMixin

class User(UserNotificationsMixin, AbstractUser):
    pass

URL Configuration

from django.urls import path, include

urlpatterns = [
    path('notifications/', include('whistle.urls')),
]

This provides:

  • notifications:list - Notification list view
  • notifications:settings - User preference management
  • notifications:read_notification - Mark notification as read via signed hash

Middleware

Add ReadNotificationMiddleware to automatically mark notifications as read:

MIDDLEWARE = [
    # ...
    'whistle.middleware.ReadNotificationMiddleware',
]

The middleware provides two features:

  1. URL parameter tracking - Marks a notification as read when the URL contains the read-notification query parameter (configurable via WHISTLE_URL_PARAM) with the notification ID.

  2. DetailView auto-marking - Automatically marks all unread notifications as read when a user views a DetailView of an object that is related to the notification (either as object or target).

Custom Managers and Handlers

Override notification logic by creating custom managers or handlers:

# settings.py

WHISTLE_AVAILABILITY_HANDLER = "myapp.handlers.availability_handler"
WHISTLE_NOTIFICATION_MANAGER_CLASS = "myapp.managers.CustomNotificationManager"
WHISTLE_EMAIL_MANAGER_CLASS = "myapp.managers.CustomEmailManager"

Asynchronous Notifications

Enable background processing with django-rq:

# settings.py

WHISTLE_USE_RQ = True
WHISTLE_REDIS_QUEUE = 'default'

RQ_QUEUES = {
    'default': {
        'HOST': 'localhost',
        'PORT': 6379,
        'DB': 0,
    }
}

All Settings Reference

Setting Default Description
WHISTLE_NOTIFICATION_EVENTS [] Tuple of (event_name, template_string) pairs
WHISTLE_CHANNELS ['web', 'email'] Enabled notification channels
WHISTLE_AVAILABILITY_HANDLER None Path to custom availability function
WHISTLE_URL_HANDLER None Path to custom URL generation function
WHISTLE_URL_PARAM 'read-notification' Query parameter for marking notifications read
WHISTLE_CACHE_TIMEOUT DEFAULT_TIMEOUT Cache duration (Django's default)
WHISTLE_USE_RQ True Enable background job processing
WHISTLE_REDIS_QUEUE 'default' Redis queue name for background jobs
WHISTLE_SIGNING_KEY SECRET_KEY Key for signing notification hashes
WHISTLE_SIGNING_SALT 'whistle' Salt for signing notification hashes
WHISTLE_AUTH_USER_MODEL AUTH_USER_MODEL Custom user model
WHISTLE_OLD_THRESHOLD None Age threshold for old notifications (timedelta)
WHISTLE_DEFAULT_NOTIFICATIONS {} Default channel/event settings
WHISTLE_NOTIFICATION_MANAGER_CLASS 'whistle.managers.NotificationManager' Custom notification manager
WHISTLE_EMAIL_MANAGER_CLASS 'whistle.managers.EmailManager' Custom email manager

Usage

Sending Notifications

from whistle.helpers import notify

notify(
    recipient=user,
    event='ORDER_PLACED',
    actor=request.user,
    object=order,
    target=None,
    details='Additional context',
)

Email Templates

Create event-specific email templates at templates/whistle/mails/{event_name}.txt. Falls back to templates/whistle/mails/new_notification.txt.

Management Commands

# Delete old notifications
python manage.py delete_old_notifications [--dry-run]

# Copy notification settings between channels
python manage.py copy_channel_settings <from_channel> <to_channel> [--delete]

REST API

If using Django REST Framework, the package provides:

  • NotificationViewSet - Read-only viewset for user notifications
  • MarkNotificationsAsReadAPIView - PATCH endpoint to mark notifications as read

Managers

NotificationQuerySet

Custom queryset with filtering methods for notifications:

Method Description
unread() Filter unread notifications
mark_as_read() Bulk update notifications as read
for_recipient(user) Filter by recipient user
of_object(obj) Filter by related object
of_target(target) Filter by target object
of_object_or_target(obj) Filter by either object or target
old(threshold) Filter notifications older than threshold
not_old(threshold) Filter notifications newer than threshold

NotificationManager

Handles notification creation and dispatch logic. Key methods:

Method Description
notify(recipient, event, actor, object, target, details) Create and dispatch notification to enabled channels
is_channel_available(user, channel) Check if channel is available for user
is_notification_enabled(user, channel, event) Check if notification is enabled (availability + user preferences)
get_description(event, actor, object, target) Render notification text from event template
get_push_config(notification) Build FCM push notification configuration
push_notification(notification) Send push notification via FCM
mail_notification(notification) Trigger email notification

Signals emitted:

  • notification_emailed - Sent after email notification is dispatched
  • notification_pushed - Sent after push notification is dispatched

EmailManager

Handles email notification rendering and sending:

Method Description
send_mail(recipient, event, **kwargs) Send email notification (sync or via RQ)
prepare_email(recipient, event, **kwargs) Build email subject, message, and HTML content
load_template(template_type, recipient, event) Load event-specific or default template
get_mail_subject(context) Generate subject with site name prefix
get_mail_context(recipient, event, **kwargs) Build template context with descriptions

Background Jobs

When WHISTLE_USE_RQ=True, notifications and emails are processed asynchronously via django-rq:

Job Description
notify_in_background(recipient, event, ...) Queue notification creation
send_mail_in_background(subject, message, ...) Queue email sending

Jobs are dispatched to the queue specified by WHISTLE_REDIS_QUEUE (default: 'default').

Versioning

We use SemVer for versioning.

Authors

See also the list of contributors.

License

This project is licensed under the BSD License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_whistle-7.0.0.tar.gz (24.0 kB view details)

Uploaded Source

File details

Details for the file django_whistle-7.0.0.tar.gz.

File metadata

  • Download URL: django_whistle-7.0.0.tar.gz
  • Upload date:
  • Size: 24.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for django_whistle-7.0.0.tar.gz
Algorithm Hash digest
SHA256 07feb66b3f7b4bcb7b94108bc190cc5111becdc316d740fb05fd15e898251a1d
MD5 93d5897aea838c8755fad102bcc481e0
BLAKE2b-256 52f9aacc9d241a0c49bcb9c240daae8aa0835232441529866d4e900fd0592668

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page