Notifications App Reference¶
The Notifications app provides an in-app notification system with automatic triggers, deduplication, bulk management, and AJAX support for marking notifications as read or deleting them.
Overview¶
Location: app/notifications/
Purpose: In-app notification system with automatic triggers, deduplication, and cleanup
Key Model: Notification
Dependencies: organizations (org scoping, user orgs), hives (operations, inspections), warehouse (low stock), dataexchange (export/import jobs)
File Structure¶
notifications/
├── models.py # Notification model (1 model)
├── views.py # 5 views
├── services.py # 7 notification creation functions
├── signals.py # 2 active signal handlers (export/import)
├── context_processors.py # Unread count + recent notifications context
├── urls.py # 5 URL patterns
├── admin.py # NotificationAdmin with fieldsets
├── apps.py # AppConfig (imports signals in ready())
├── management/
│ └── commands/
│ └── cleanup_old_notifications.py # Archive/delete old notifications
├── tests/
│ ├── test_models.py
│ ├── test_services.py
│ ├── test_signals.py
│ └── test_views.py
└── templates/notifications/
├── base_notifications.html
├── notification_list.html
└── _notification_item.html
Models¶
Notification¶
Location: app/notifications/models.py
Categories: todo, dashboard, export_import, system
Priorities: low, medium, high, urgent
Fields:
| Field | Type | Description |
|---|---|---|
recipient |
FK(User) | Notification recipient |
organization |
FK(Organization) | Related organization |
category |
CharField(20) | Notification category |
priority |
CharField(10) | Urgency level (default: medium) |
title |
CharField(200) | Notification title |
message |
TextField | Full message text |
link |
CharField(500) | Internal URL path (e.g., /activities/123/) |
content_type |
FK(ContentType) | For GenericForeignKey (nullable) |
object_id |
PositiveIntegerField | For GenericForeignKey (nullable) |
is_read |
BooleanField | Read status (default: False) |
read_at |
DateTimeField | When marked as read (nullable) |
is_archived |
BooleanField | Archive status (default: False) |
created_at |
DateTimeField | Auto-set on creation |
updated_at |
DateTimeField | Auto-set on save |
Methods:
mark_as_read()-- Sets is_read=True and read_at=nowmark_as_unread()-- Sets is_read=False and read_at=Nonecategory_icon()-- Returns Bootstrap icon class for categorypriority_color()-- Returns Bootstrap color class for priorityuser_can_view(user)-- Returns True if user is the recipient
Indexes: (recipient, is_read, -created_at), (organization, -created_at), (category)
Views¶
| View | Purpose |
|---|---|
| NotificationListView | Paginated list (20/page) with category/status/archive filters. Provides counts by category. |
| NotificationMarkReadView | AJAX POST to mark single notification as read. Returns JSON with unread count. |
| NotificationMarkAllReadView | POST to mark all user notifications as read. Redirects to referer. |
| NotificationDeleteView | POST to delete notification (AJAX JSON response or form redirect). |
| NotificationDeleteCategoryView | POST to delete all notifications in a specific category or all notifications. |
Services¶
Location: app/notifications/services.py
Core Functions¶
create_notification() -- Core creation with deduplication. Checks for duplicate notifications (same recipient, organization, category, title) within a configurable dedup_hours window (default: 24 hours). Supports linking to any model via GenericForeignKey.
create_dashboard_notifications() -- Checks three alert conditions and creates notifications:
- Overdue operations (scheduled but not completed, past scheduled date)
- Hives needing inspection (not inspected in 7+ days or never inspected)
- Low stock items (quantity below minimum quantity)
Specialized Notification Functions¶
| Function | Purpose | Dedup Window |
|---|---|---|
notify_todo_item_completed() |
Notify when operation todo item is completed | 1 hour |
notify_todo_checklist_complete() |
Notify when all items in operation checklist are done | 1 hour |
notify_new_todo_assigned() |
Notify assignee of new operation (skips self-assignment) | 1 hour |
notify_export_job_complete() |
Notify on export completion or failure | 1 hour |
notify_import_job_complete() |
Notify on import completion or failure | 1 hour |
Signals¶
Location: app/notifications/signals.py
Note
Todo signal handlers have been removed (activities app migrated to operation-specific models). Only export/import handlers are active.
| Signal | Trigger | Action |
|---|---|---|
| handle_export_job_saved | post_save on ExportJob (update only) |
Notify on status 'completed' or 'failed' |
| handle_import_job_saved | post_save on ImportJob (update only) |
Notify on status 'completed' or 'failed' |
Context Processors¶
Location: app/notifications/context_processors.py
notification_context()¶
Adds the following variables to all templates:
unread_notification_count-- Count of unread, non-archived notifications for the current userrecent_notifications-- 5 most recent notifications (unread first, then sorted by creation date)
Returns zeros and empty lists for anonymous users. Filters notifications by the user's accessible organizations.
Management Commands¶
cleanup_old_notifications¶
Archives and deletes old notifications based on retention policy.
# Preview changes without modifying data
python manage.py cleanup_old_notifications --dry-run
# Run with default settings (archive after 90 days, delete after 180 days)
python manage.py cleanup_old_notifications
# Custom retention periods
python manage.py cleanup_old_notifications --retention-days 60 --delete-after-days 120
Settings (configurable via Django settings):
| Setting | Default | Description |
|---|---|---|
NOTIFICATION_RETENTION_DAYS |
90 | Days before notifications are archived |
NOTIFICATION_DELETE_AFTER_DAYS |
180 | Days before notifications are permanently deleted |
URL Patterns¶
notifications/ → NotificationListView (notification-list)
notifications/<int:pk>/mark-read/ → NotificationMarkReadView (notification-mark-read)
notifications/mark-all-read/ → NotificationMarkAllReadView (notification-mark-all-read)
notifications/<int:pk>/delete/ → NotificationDeleteView (notification-delete)
notifications/delete-category/<str:category>/ → NotificationDeleteCategoryView (notification-delete-category)
Admin¶
The Notification model is registered with the Django admin interface, providing:
- List display: ID, recipient, organization, category, priority, title, read status, archived status, creation date
- Filters: Category, priority, read status, archived status, creation date
- Search: Title, message, recipient username
- Fieldsets: Recipient, Notification Content, Related Object (collapsible), Status, Timestamps (collapsible)
Key Features¶
- Automatic Triggers: Export/import job completions trigger notifications via signals
- Dashboard Alerts: Overdue operations, hive inspection reminders (7+ days), low stock warnings
- Deduplication: Prevents duplicate notifications within configurable timeframes (1-24 hours)
- AJAX Support: Mark read and delete via AJAX with JSON responses
- Bulk Operations: Mark all as read, delete by category, delete all notifications
- Generic Relations: Link notifications to any model via GenericForeignKey
- Priority System: Visual indicators (color-coded) for urgency levels
- Cleanup Command: Automated archival and deletion of old notifications
- Context Processor: Unread count and recent notifications available globally in templates
See Also¶
- DataExchange App Reference - Triggers export/import notifications
- Home App Reference - Dashboard alerts
- Organizations App Reference - Organization scoping