Skip to content

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=now
  • mark_as_unread() -- Sets is_read=False and read_at=None
  • category_icon() -- Returns Bootstrap icon class for category
  • priority_color() -- Returns Bootstrap color class for priority
  • user_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 user
  • recent_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