0
# Django Dynamic Preferences
1
2
A Django package that provides dynamic preferences/settings functionality, allowing configuration values to be stored in the database and managed through Django's admin interface or REST API. This enables runtime configuration changes without server restarts, supporting both global settings and per-user preferences.
3
4
## Package Information
5
6
- **Package Name**: django-dynamic-preferences
7
- **Language**: Python
8
- **Framework**: Django 4.2+
9
- **Installation**: `pip install django-dynamic-preferences`
10
11
## Core Imports
12
13
```python
14
from dynamic_preferences.registries import global_preferences_registry
15
from dynamic_preferences.types import BooleanPreference, StringPreference
16
from dynamic_preferences.preferences import Section
17
```
18
19
For user-specific preferences:
20
21
```python
22
from dynamic_preferences.users.registries import user_preferences_registry
23
```
24
25
## Basic Usage
26
27
```python
28
# settings.py
29
INSTALLED_APPS = [
30
# ...
31
'dynamic_preferences',
32
]
33
34
# Create a preferences registry file (e.g., dynamic_preferences_registry.py)
35
from dynamic_preferences.preferences import Section
36
from dynamic_preferences.registries import global_preferences_registry
37
from dynamic_preferences.types import BooleanPreference, StringPreference
38
39
# Define sections
40
general = Section('general')
41
ui = Section('ui')
42
43
# Register preferences
44
@global_preferences_registry.register
45
class SiteTitle(StringPreference):
46
section = general
47
name = 'title'
48
default = 'My Site'
49
verbose_name = 'Site title'
50
51
@global_preferences_registry.register
52
class MaintenanceMode(BooleanPreference):
53
section = general
54
name = 'maintenance_mode'
55
default = False
56
verbose_name = 'Maintenance mode'
57
58
# Usage in views/code
59
from dynamic_preferences.registries import global_preferences_registry
60
61
def my_view(request):
62
global_preferences = global_preferences_registry.manager()
63
site_title = global_preferences['general__title']
64
maintenance_mode = global_preferences['general__maintenance_mode']
65
66
# Update preferences
67
global_preferences['general__title'] = 'New Site Title'
68
69
return render(request, 'template.html', {
70
'site_title': site_title,
71
'maintenance_mode': maintenance_mode,
72
})
73
```
74
75
## Architecture
76
77
Django Dynamic Preferences uses a layered architecture:
78
79
- **Registries**: Centralized preference management and organization
80
- **Preference Types**: Type-safe value handling with automatic serialization
81
- **Models**: Database storage with Django ORM integration
82
- **Managers**: Cached preference access with automatic database synchronization
83
- **Admin Integration**: Built-in Django admin interface for preference management
84
- **Forms/Views**: Web interface components for preference editing
85
- **REST API**: Django REST Framework integration for API access
86
87
## Capabilities
88
89
### Core Models and Managers
90
91
Database models for storing preferences and manager classes for cached preference access with automatic synchronization.
92
93
```python { .api }
94
class BasePreferenceModel(models.Model):
95
section = models.CharField(max_length=150)
96
name = models.CharField(max_length=150)
97
raw_value = models.TextField()
98
99
@property
100
def value(self): ...
101
@value.setter
102
def value(self, value): ...
103
104
class GlobalPreferenceModel(BasePreferenceModel): ...
105
106
class PreferencesManager:
107
def __getitem__(self, key: str): ...
108
def __setitem__(self, key: str, value): ...
109
def get(self, key: str, no_cache: bool = False): ...
110
def all(self) -> dict: ...
111
```
112
113
[Core Models and Managers](./core-models.md)
114
115
### Preference Types
116
117
Built-in preference types with automatic serialization, form field generation, and validation for various data types.
118
119
```python { .api }
120
class BasePreferenceType:
121
field_class = None
122
serializer = None
123
default = None
124
125
def validate(self, value): ...
126
def api_repr(self, value): ...
127
128
class BooleanPreference(BasePreferenceType): ...
129
class StringPreference(BasePreferenceType): ...
130
class IntegerPreference(BasePreferenceType): ...
131
class ChoicePreference(BasePreferenceType):
132
choices = ()
133
class ModelChoicePreference(BasePreferenceType):
134
model = None
135
queryset = None
136
```
137
138
[Preference Types](./preference-types.md)
139
140
### Registries
141
142
Registration and organization system for preferences with section support and manager instantiation.
143
144
```python { .api }
145
class PreferenceRegistry:
146
name: str
147
preference_model = None
148
149
def register(self, preference_class): ...
150
def get(self, name: str, section: str = None): ...
151
def manager(self, **kwargs) -> PreferencesManager: ...
152
def sections(self) -> list: ...
153
154
class GlobalPreferenceRegistry(PreferenceRegistry): ...
155
156
global_preferences_registry: GlobalPreferenceRegistry
157
```
158
159
[Registries](./registries.md)
160
161
### Django Admin Integration
162
163
Complete Django admin interface integration with custom admin classes, forms, and filters for preference management.
164
165
```python { .api }
166
class DynamicPreferenceAdmin(admin.ModelAdmin):
167
list_display = ('verbose_name', 'name', 'section_name', 'help_text', 'raw_value', 'default_value')
168
readonly_fields = ('name', 'section_name', 'default_value')
169
search_fields = ('name', 'section', 'raw_value')
170
171
class GlobalPreferenceAdmin(DynamicPreferenceAdmin): ...
172
```
173
174
[Django Admin Integration](./admin-integration.md)
175
176
### REST API
177
178
Django REST Framework integration providing serializers, viewsets, and permissions for API-based preference management.
179
180
```python { .api }
181
class PreferenceSerializer(serializers.Serializer):
182
section = serializers.CharField(read_only=True)
183
name = serializers.CharField(read_only=True)
184
value = PreferenceValueField()
185
verbose_name = serializers.SerializerMethodField()
186
187
class GlobalPreferencesViewSet(viewsets.GenericViewSet):
188
def list(self, request): ...
189
def retrieve(self, request, pk=None): ...
190
def update(self, request, pk=None): ...
191
def bulk(self, request): ...
192
```
193
194
[REST API](./rest-api.md)
195
196
### User Preferences
197
198
User-specific preferences system with models, forms, admin integration, and API support for per-user settings.
199
200
```python { .api }
201
class UserPreferenceModel(PerInstancePreferenceModel):
202
instance = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
203
204
class UserPreferenceRegistry(PerInstancePreferenceRegistry): ...
205
206
user_preferences_registry: UserPreferenceRegistry
207
208
class UserPreferencesViewSet(PerInstancePreferenceViewSet): ...
209
```
210
211
[User Preferences](./user-preferences.md)
212
213
### Forms and Views
214
215
Django forms and views for web-based preference editing with dynamic form generation and validation.
216
217
```python { .api }
218
class AbstractSinglePreferenceForm(forms.ModelForm):
219
def __init__(self, *args, **kwargs): ...
220
def save(self, commit=True): ...
221
222
class PreferenceForm(forms.Form):
223
registry = None
224
def update_preferences(self, **kwargs): ...
225
226
def preference_form_builder(form_base_class, preferences=None, **options): ...
227
def global_preference_form_builder(preferences=None, **options): ...
228
229
class PreferenceFormView(FormView):
230
registry = None
231
def get_form_class(self): ...
232
```
233
234
[Forms and Views](./forms-views.md)
235
236
### Serialization
237
238
Value serialization system for database storage with support for complex Python objects and custom serialization logic.
239
240
```python { .api }
241
class BaseSerializer:
242
@classmethod
243
def serialize(cls, value, **kwargs) -> str: ...
244
@classmethod
245
def deserialize(cls, value, **kwargs): ...
246
247
class BooleanSerializer(BaseSerializer): ...
248
class StringSerializer(BaseSerializer): ...
249
class ModelSerializer(InstanciatedSerializer): ...
250
class FileSerializer(InstanciatedSerializer): ...
251
```
252
253
[Serialization](./serialization.md)
254
255
### Signals
256
257
Django signal system integration for reacting to preference changes with custom logic, logging, or cache invalidation.
258
259
```python { .api }
260
from django.dispatch import Signal
261
262
preference_updated: Signal
263
```
264
265
[Signals](./signals.md)
266
267
### Django Integration
268
269
Django framework integration features including template context processors for automatic preference injection into template context.
270
271
```python { .api }
272
def global_preferences(request):
273
"""Template context processor for global preferences."""
274
...
275
```
276
277
[Django Integration](./django-integration.md)
278
279
## Types
280
281
```python { .api }
282
class Section:
283
def __init__(self, name: str, verbose_name: str = None): ...
284
name: str
285
verbose_name: str
286
287
class AbstractPreference:
288
section: Section
289
name: str
290
default: Any
291
verbose_name: str
292
help_text: str
293
294
def identifier(self) -> str: ...
295
296
# Constants
297
EMPTY_SECTION: Section
298
UNSET: UnsetValue
299
300
# Exceptions
301
class DynamicPreferencesException(Exception): ...
302
class NotFoundInRegistry(DynamicPreferencesException, KeyError): ...
303
class MissingDefault(DynamicPreferencesException): ...
304
```