0
# Configuration
1
2
Configurable settings for pagination, soft deletion, JSON field usage, caching, and other behavioral options with sensible defaults and Django settings integration.
3
4
## Capabilities
5
6
### Settings Function
7
8
Function to retrieve merged configuration combining defaults with user-specified settings.
9
10
```python { .api }
11
def get_config():
12
"""
13
Get merged configuration with user settings and defaults.
14
15
Returns:
16
dict: Configuration dictionary with all settings
17
18
Configuration Keys:
19
PAGINATE_BY (int): Number of notifications per page (default: 20)
20
USE_JSONFIELD (bool): Enable JSONField for extra data (default: False)
21
SOFT_DELETE (bool): Use soft deletion instead of hard delete (default: False)
22
NUM_TO_FETCH (int): Default number for API endpoints (default: 10)
23
CACHE_TIMEOUT (int): Cache timeout in seconds (default: 2)
24
25
Django Setting:
26
DJANGO_NOTIFICATIONS_CONFIG (dict): User configuration overrides
27
"""
28
```
29
30
### Default Configuration
31
32
```python { .api }
33
CONFIG_DEFAULTS = {
34
'PAGINATE_BY': 20,
35
'USE_JSONFIELD': False,
36
'SOFT_DELETE': False,
37
'NUM_TO_FETCH': 10,
38
'CACHE_TIMEOUT': 2,
39
}
40
```
41
42
### Usage Examples
43
44
#### Basic Configuration Setup
45
46
```python
47
# In your Django settings.py
48
DJANGO_NOTIFICATIONS_CONFIG = {
49
'PAGINATE_BY': 25, # Show 25 notifications per page
50
'USE_JSONFIELD': True, # Enable extra data storage
51
'SOFT_DELETE': True, # Use soft deletion
52
'NUM_TO_FETCH': 15, # Fetch 15 notifications by default in API
53
'CACHE_TIMEOUT': 30, # Cache notification counts for 30 seconds
54
}
55
56
# The configuration is automatically loaded by the package
57
from notifications.settings import get_config
58
59
config = get_config()
60
print(config['PAGINATE_BY']) # Output: 25
61
print(config['SOFT_DELETE']) # Output: True
62
```
63
64
#### Production Configuration
65
66
```python
67
# settings/production.py
68
DJANGO_NOTIFICATIONS_CONFIG = {
69
# Higher pagination for performance
70
'PAGINATE_BY': 50,
71
72
# Enable JSON field for rich notification data
73
'USE_JSONFIELD': True,
74
75
# Use soft delete to maintain data integrity
76
'SOFT_DELETE': True,
77
78
# Fetch more notifications for mobile apps
79
'NUM_TO_FETCH': 25,
80
81
# Longer cache timeout for better performance
82
'CACHE_TIMEOUT': 300, # 5 minutes
83
}
84
```
85
86
#### Development Configuration
87
88
```python
89
# settings/development.py
90
DJANGO_NOTIFICATIONS_CONFIG = {
91
# Smaller pagination for easier testing
92
'PAGINATE_BY': 5,
93
94
# Enable JSON field for testing data structures
95
'USE_JSONFIELD': True,
96
97
# Disable soft delete for easier debugging
98
'SOFT_DELETE': False,
99
100
# Fetch fewer notifications for faster development
101
'NUM_TO_FETCH': 5,
102
103
# Short cache timeout for immediate feedback
104
'CACHE_TIMEOUT': 1,
105
}
106
```
107
108
#### Configuration-Aware Code
109
110
```python
111
from notifications.settings import get_config
112
113
def create_notification_page(request):
114
"""Create paginated notification view using configuration."""
115
config = get_config()
116
117
notifications = request.user.notifications.all()
118
119
# Use configured pagination
120
paginator = Paginator(notifications, config['PAGINATE_BY'])
121
page_number = request.GET.get('page')
122
page_obj = paginator.get_page(page_number)
123
124
return render(request, 'notifications/list.html', {
125
'notifications': page_obj,
126
'config': config
127
})
128
129
def send_rich_notification(sender, recipient, verb, **extra_data):
130
"""Send notification with optional JSON data based on configuration."""
131
config = get_config()
132
133
notification_kwargs = {
134
'sender': sender,
135
'recipient': recipient,
136
'verb': verb
137
}
138
139
# Only include extra data if JSON field is enabled
140
if config['USE_JSONFIELD'] and extra_data:
141
notification_kwargs.update(extra_data)
142
143
notify.send(**notification_kwargs)
144
145
def get_cached_notification_count(user):
146
"""Get notification count with configured cache timeout."""
147
config = get_config()
148
149
cache_key = f'notification_count_{user.id}'
150
count = cache.get(cache_key)
151
152
if count is None:
153
count = user.notifications.unread().count()
154
cache.set(cache_key, count, config['CACHE_TIMEOUT'])
155
156
return count
157
```
158
159
#### Conditional Features Based on Configuration
160
161
```python
162
from notifications.settings import get_config
163
164
class NotificationManager:
165
def __init__(self):
166
self.config = get_config()
167
168
def delete_notification(self, notification):
169
"""Delete notification using configured deletion method."""
170
if self.config['SOFT_DELETE']:
171
notification.deleted = True
172
notification.save()
173
else:
174
notification.delete()
175
176
def get_active_notifications(self, user):
177
"""Get notifications respecting soft delete configuration."""
178
notifications = user.notifications.all()
179
180
if self.config['SOFT_DELETE']:
181
notifications = notifications.filter(deleted=False)
182
183
return notifications
184
185
def prepare_notification_data(self, notification, extra_data=None):
186
"""Prepare notification data based on configuration."""
187
data = {
188
'actor': str(notification.actor),
189
'verb': notification.verb,
190
'timestamp': notification.timestamp.isoformat(),
191
}
192
193
# Include JSON data if enabled
194
if self.config['USE_JSONFIELD'] and notification.data:
195
data['extra_data'] = notification.data
196
197
# Include additional data if provided and JSON field enabled
198
if self.config['USE_JSONFIELD'] and extra_data:
199
data.update(extra_data)
200
201
return data
202
203
# Usage
204
manager = NotificationManager()
205
user_notifications = manager.get_active_notifications(user)
206
```
207
208
#### API Configuration
209
210
```python
211
from notifications.settings import get_config
212
from django.http import JsonResponse
213
214
def notification_api_endpoint(request):
215
"""API endpoint that respects configuration settings."""
216
config = get_config()
217
218
# Use configured default fetch count
219
max_count = request.GET.get('max', config['NUM_TO_FETCH'])
220
try:
221
max_count = min(int(max_count), 100) # Cap at 100
222
except (ValueError, TypeError):
223
max_count = config['NUM_TO_FETCH']
224
225
notifications = request.user.notifications.unread()[:max_count]
226
227
notification_list = []
228
for notification in notifications:
229
notif_data = {
230
'id': notification.id,
231
'actor': str(notification.actor),
232
'verb': notification.verb,
233
'timestamp': notification.timestamp.isoformat(),
234
}
235
236
# Include JSON data if configured
237
if config['USE_JSONFIELD'] and notification.data:
238
notif_data['data'] = notification.data
239
240
notification_list.append(notif_data)
241
242
return JsonResponse({
243
'notifications': notification_list,
244
'count': len(notification_list),
245
'config': {
246
'max_per_request': config['NUM_TO_FETCH'],
247
'pagination_size': config['PAGINATE_BY'],
248
'cache_timeout': config['CACHE_TIMEOUT']
249
}
250
})
251
```
252
253
#### Template Configuration Context
254
255
```python
256
from notifications.settings import get_config
257
258
def add_config_to_context(request):
259
"""Context processor to add configuration to templates."""
260
return {
261
'notifications_config': get_config()
262
}
263
264
# In settings.py
265
TEMPLATES = [
266
{
267
'BACKEND': 'django.template.backends.django.DjangoTemplates',
268
'OPTIONS': {
269
'context_processors': [
270
# ... other context processors
271
'myapp.context_processors.add_config_to_context',
272
],
273
},
274
},
275
]
276
```
277
278
```html
279
<!-- In templates -->
280
{% load notifications_tags %}
281
282
<!-- Use configuration in templates -->
283
<div class="notifications-config">
284
<p>Showing {{ notifications_config.PAGINATE_BY }} notifications per page</p>
285
286
{% if notifications_config.SOFT_DELETE %}
287
<p>Deleted notifications are preserved</p>
288
{% endif %}
289
290
{% if notifications_config.USE_JSONFIELD %}
291
<!-- Show rich notification data -->
292
{% for notification in notifications %}
293
{% if notification.data %}
294
<div class="notification-extra-data">
295
{{ notification.data|safe }}
296
</div>
297
{% endif %}
298
{% endfor %}
299
{% endif %}
300
</div>
301
302
<!-- Configure template tag with settings -->
303
{% register_notify_callbacks
304
fetch=notifications_config.NUM_TO_FETCH
305
refresh_period=notifications_config.CACHE_TIMEOUT
306
%}
307
```
308
309
#### Migration and Configuration Changes
310
311
```python
312
# Custom management command to handle configuration changes
313
from django.core.management.base import BaseCommand
314
from notifications.settings import get_config
315
from notifications.models import Notification
316
317
class Command(BaseCommand):
318
help = 'Migrate notifications based on configuration changes'
319
320
def handle(self, *args, **options):
321
config = get_config()
322
323
if config['SOFT_DELETE']:
324
# Ensure deleted field exists and is properly indexed
325
self.stdout.write("Soft delete is enabled")
326
327
# Count notifications that would be affected
328
hard_deleted_count = Notification.objects.filter(deleted=True).count()
329
self.stdout.write(f"Found {hard_deleted_count} soft-deleted notifications")
330
331
else:
332
# Warn about data that might be lost
333
soft_deleted_count = Notification.objects.filter(deleted=True).count()
334
if soft_deleted_count > 0:
335
self.stdout.write(
336
self.style.WARNING(
337
f"Warning: {soft_deleted_count} soft-deleted notifications exist "
338
"but SOFT_DELETE is False. These may not be visible."
339
)
340
)
341
342
if config['USE_JSONFIELD']:
343
# Check for notifications with JSON data
344
with_data_count = Notification.objects.exclude(data__isnull=True).count()
345
self.stdout.write(f"Found {with_data_count} notifications with JSON data")
346
347
self.stdout.write(
348
self.style.SUCCESS(f"Configuration check complete. Current settings: {config}")
349
)
350
```
351
352
#### Environment-Specific Configuration
353
354
```python
355
# settings/base.py
356
import os
357
358
# Base notification configuration
359
DJANGO_NOTIFICATIONS_CONFIG = {
360
'PAGINATE_BY': int(os.environ.get('NOTIFICATIONS_PAGINATE_BY', '20')),
361
'USE_JSONFIELD': os.environ.get('NOTIFICATIONS_USE_JSONFIELD', 'False').lower() == 'true',
362
'SOFT_DELETE': os.environ.get('NOTIFICATIONS_SOFT_DELETE', 'False').lower() == 'true',
363
'NUM_TO_FETCH': int(os.environ.get('NOTIFICATIONS_NUM_TO_FETCH', '10')),
364
'CACHE_TIMEOUT': int(os.environ.get('NOTIFICATIONS_CACHE_TIMEOUT', '2')),
365
}
366
367
# Environment variables:
368
# NOTIFICATIONS_PAGINATE_BY=25
369
# NOTIFICATIONS_USE_JSONFIELD=true
370
# NOTIFICATIONS_SOFT_DELETE=true
371
# NOTIFICATIONS_NUM_TO_FETCH=15
372
# NOTIFICATIONS_CACHE_TIMEOUT=30
373
```