or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

admin-integration.mdapi-endpoints.mdconfiguration.mdcore-system.mdindex.mdsignals.mdtemplate-integration.mdutilities.mdweb-interface.md

configuration.mddocs/

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

```