0
# Signal System
1
2
Django signal system for creating notifications with flexible actor-verb-object patterns. Supports individual users, groups, and querysets as recipients with automatic notification creation and handling.
3
4
## Capabilities
5
6
### Notification Signal
7
8
The main Django signal used to trigger notification creation with flexible recipient handling and optional object references.
9
10
```python { .api }
11
from django.dispatch import Signal
12
13
notify = Signal()
14
```
15
16
### Signal Handler Function
17
18
The core function that processes notification signals and creates notification instances with support for multiple recipient types and optional objects.
19
20
```python { .api }
21
def notify_handler(verb, **kwargs):
22
"""
23
Create Notification instances from signal calls.
24
25
Args:
26
verb (str): Action verb describing what happened
27
**kwargs: Additional parameters for notification creation
28
29
Required kwargs:
30
recipient: User, Group, QuerySet, or list of Users to notify
31
sender: Actor object that performed the action
32
33
Optional kwargs:
34
target: Target object the action was performed on
35
action_object: Object linked to the action itself
36
public (bool): Whether notification is public (default: True)
37
description (str): Text description of the notification
38
timestamp (datetime): Custom timestamp (default: now)
39
level (str): Notification level (default: 'info')
40
actor_for_concrete_model (bool): ContentType behavior (default: True)
41
target_for_concrete_model (bool): ContentType behavior (default: True)
42
action_object_for_concrete_model (bool): ContentType behavior (default: True)
43
Additional kwargs stored in data JSONField if USE_JSONFIELD=True
44
45
Returns:
46
list: List of created Notification instances
47
48
Raises:
49
Various exceptions based on model validation and database constraints
50
"""
51
```
52
53
### Usage Examples
54
55
#### Basic Notification Creation
56
57
```python
58
from django.contrib.auth.models import User
59
from notifications.signals import notify
60
61
# Get users
62
actor = User.objects.get(username='john')
63
recipient = User.objects.get(username='jane')
64
65
# Send simple notification
66
notify.send(
67
sender=actor, # Required: who performed the action
68
recipient=recipient, # Required: who should be notified
69
verb='followed', # Required: what action was performed
70
description='John started following you'
71
)
72
```
73
74
#### Notification with Target Object
75
76
```python
77
from myapp.models import Post
78
79
post = Post.objects.get(id=1)
80
81
# Notify about action on target object
82
notify.send(
83
sender=actor,
84
recipient=post.author, # Notify the post author
85
verb='liked',
86
target=post, # The post that was liked
87
description=f'{actor.username} liked your post "{post.title}"'
88
)
89
```
90
91
#### Notification with Action Object
92
93
```python
94
from myapp.models import Comment
95
96
comment = Comment.objects.create(
97
post=post,
98
author=actor,
99
content='Great post!'
100
)
101
102
# Notify about new comment (action object) on post (target)
103
notify.send(
104
sender=actor,
105
recipient=post.author,
106
verb='commented on',
107
action_object=comment, # The comment that was created
108
target=post, # The post that was commented on
109
description=f'{actor.username} commented on your post'
110
)
111
```
112
113
#### Multiple Recipients
114
115
```python
116
# Notify multiple users individually
117
recipients = [user1, user2, user3]
118
notify.send(
119
sender=actor,
120
recipient=recipients, # List of users
121
verb='posted',
122
target=post,
123
description='New post available'
124
)
125
126
# Notify all users in a group
127
from django.contrib.auth.models import Group
128
editors = Group.objects.get(name='editors')
129
notify.send(
130
sender=actor,
131
recipient=editors, # All users in group will be notified
132
verb='submitted',
133
target=post,
134
description='New post submitted for review'
135
)
136
137
# Notify users from queryset
138
active_users = User.objects.filter(is_active=True)
139
notify.send(
140
sender=actor,
141
recipient=active_users, # All active users
142
verb='announced',
143
description='System maintenance announcement'
144
)
145
```
146
147
#### Notification Levels and Additional Data
148
149
```python
150
# Set notification level
151
notify.send(
152
sender=actor,
153
recipient=recipient,
154
verb='failed to process',
155
level='error', # 'success', 'info', 'warning', 'error'
156
description='Payment processing failed'
157
)
158
159
# Include additional data (requires USE_JSONFIELD=True)
160
notify.send(
161
sender=actor,
162
recipient=recipient,
163
verb='earned',
164
description='Achievement unlocked!',
165
# Additional data stored in JSONField
166
achievement_name='First Post',
167
points_earned=100,
168
badge_url='/static/badges/first-post.png'
169
)
170
```
171
172
#### Custom Timestamps and Visibility
173
174
```python
175
from django.utils import timezone
176
from datetime import timedelta
177
178
# Custom timestamp
179
past_time = timezone.now() - timedelta(hours=2)
180
notify.send(
181
sender=actor,
182
recipient=recipient,
183
verb='completed',
184
timestamp=past_time,
185
description='Task completed 2 hours ago'
186
)
187
188
# Private notification (not public)
189
notify.send(
190
sender=actor,
191
recipient=recipient,
192
verb='sent private message',
193
public=False, # Only visible to recipient
194
description='You have a private message'
195
)
196
```
197
198
#### Signal Connection
199
200
The signal handler is automatically connected when the app loads:
201
202
```python
203
# Automatic connection in notifications/base/models.py
204
from notifications.signals import notify
205
from notifications.base.models import notify_handler
206
207
notify.connect(notify_handler, dispatch_uid='notifications.models.notification')
208
```
209
210
#### Using from App Ready Method
211
212
For consistent signal access, the notify signal is also available directly from the notifications module:
213
214
```python
215
# Available after app is ready
216
import notifications
217
notifications.notify.send(
218
sender=actor,
219
recipient=recipient,
220
verb='updated',
221
description='Profile updated'
222
)
223
```
224
225
#### Error Handling
226
227
```python
228
try:
229
notify.send(
230
sender=actor,
231
recipient=recipient,
232
verb='performed action',
233
target=some_object
234
)
235
except Exception as e:
236
# Handle notification creation errors
237
logger.error(f"Failed to create notification: {e}")
238
# Application logic continues normally
239
```
240
241
#### Integration with Django Signals
242
243
```python
244
from django.db.models.signals import post_save
245
from django.dispatch import receiver
246
from myapp.models import BlogPost
247
248
@receiver(post_save, sender=BlogPost)
249
def notify_blog_post_created(sender, instance, created, **kwargs):
250
if created:
251
# Notify followers when new blog post is created
252
followers = instance.author.followers.all()
253
if followers.exists():
254
notify.send(
255
sender=instance.author,
256
recipient=followers,
257
verb='published',
258
target=instance,
259
description=f'New blog post: {instance.title}'
260
)
261
```