6.8 KiB
User-Specific Notifications Implementation
Overview
The notifications system has been enhanced to support three types of notifications:
- Personal Notifications - Targeted to a specific user
- General Notifications - System-wide announcements visible to all users
- Role-Based Notifications - Visible to all users with specific roles
Changes Made
1. Model Updates (notifications/models.py)
New Fields Added to Notification Model:
user- Made nullable (null=True, blank=True) to support general/role-based notificationsis_general- Boolean field to mark system-wide announcementstarget_roles- JSONField containing list of role codes for role-based notifications
New Class Methods:
# Get all notifications for a user (personal, general, and role-based)
Notification.get_for_user(user)
# Create a personal notification
Notification.create_personal(user, title, message, notification_type='INFO', ...)
# Create a general notification (visible to all users)
Notification.create_general(title, message, notification_type='INFO', ...)
# Create a role-based notification
Notification.create_role_based(roles, title, message, notification_type='INFO', ...)
2. Database Migration
Migration file: notifications/migrations/0003_add_general_and_role_based_notifications.py
Changes:
- Added
is_generalfield (default=False) - Added
target_rolesfield (default=[]) - Modified
userfield to be nullable
3. Views Updates (notifications/views.py)
Updated Views:
NotificationListView- Now usesNotification.get_for_user()to fetch all relevant notificationsNotificationDropdownView- Updated to useget_for_user()methodget_unread_count()andmark_all_as_read()- Updated to work with the new filtering
New View:
BroadcastNotificationCreateView- Admin-only view to create general or role-based notifications
4. Forms (notifications/forms.py)
New Form:
BroadcastNotificationForm - Form for creating broadcast notifications with:
- Broadcast type selection (General or Role-Based)
- Target roles selection (for role-based notifications)
- Title, message, notification type, and action URL fields
- Validation to ensure roles are selected for role-based notifications
5. URLs (notifications/urls.py)
New route added:
path('inbox/broadcast/create/', views.BroadcastNotificationCreateView.as_view(),
name='broadcast_notification_create')
Usage Examples
Creating Personal Notifications (Existing Code)
from notifications.models import Notification
# Create a personal notification for a specific user
Notification.create_personal(
user=some_user,
title="Appointment Reminder",
message="You have an appointment tomorrow at 10:00 AM",
notification_type='INFO',
action_url='/appointments/123/'
)
Creating General Notifications (New)
from notifications.models import Notification
# Create a system-wide announcement
Notification.create_general(
title="System Maintenance",
message="The system will be under maintenance on Saturday from 2-4 AM",
notification_type='WARNING'
)
Creating Role-Based Notifications (New)
from notifications.models import Notification
from core.models import User
# Notify all admins and front desk staff
Notification.create_role_based(
roles=[User.Role.ADMIN, User.Role.FRONT_DESK],
title="New Patient Registration",
message="A new patient has been registered and requires file setup",
notification_type='INFO',
action_url='/patients/new/'
)
Querying Notifications
from notifications.models import Notification
# Get all notifications for a user (personal + general + role-based)
user_notifications = Notification.get_for_user(request.user)
# Get unread count
unread_count = Notification.get_unread_count(request.user)
# Mark all as read
Notification.mark_all_as_read(request.user)
Admin Interface
Admins can create broadcast notifications through the web interface:
- Navigate to
/notifications/inbox/broadcast/create/ - Select broadcast type:
- General: Visible to all users
- Role-Based: Select specific roles
- Fill in title, message, type, and optional action URL
- Submit to create the notification
Backward Compatibility
✅ Fully backward compatible - All existing code that creates personal notifications continues to work without modification:
# This still works exactly as before
Notification.objects.create(
user=some_user,
title="Test",
message="Test message",
notification_type='INFO'
)
Database Query Optimization
The get_for_user() method uses a single optimized query with OR conditions:
Q(user=user) | # Personal notifications
Q(is_general=True) | # General notifications
Q(target_roles__contains=[user.role]) # Role-based notifications
This ensures efficient retrieval of all relevant notifications in one database query.
Notification Types
Each notification can be one of four types:
INFO- Informational (blue)SUCCESS- Success message (green)WARNING- Warning (yellow/orange)ERROR- Error or critical alert (red)
Security
- Only users with
ADMINrole can create broadcast notifications - Personal notifications are only visible to the targeted user
- General notifications are visible to all authenticated users
- Role-based notifications are only visible to users with matching roles
Testing
To test the implementation:
-
Test Personal Notifications:
# Create a notification for a specific user Notification.create_personal(user, "Test", "Personal notification") # Verify only that user sees it -
Test General Notifications:
# Create a general notification Notification.create_general("Announcement", "System-wide message") # Verify all users see it -
Test Role-Based Notifications:
# Create notification for admins only Notification.create_role_based(['ADMIN'], "Admin Alert", "Admin-only message") # Verify only admin users see it
Migration Instructions
The migration has already been applied. If deploying to a new environment:
python3 manage.py migrate notifications
Summary
The notification system now supports:
- ✅ User-specific (personal) notifications
- ✅ System-wide (general) notifications
- ✅ Role-based notifications
- ✅ Backward compatibility with existing code
- ✅ Efficient database queries
- ✅ Admin interface for creating broadcasts
- ✅ Proper filtering in all views
Users will now only see notifications that are:
- Specifically addressed to them (personal)
- Marked as general (system-wide)
- Targeted to their role (role-based)
This solves the issue where users were seeing everyone's notifications.