0
# Preference Types
1
2
Built-in preference types with automatic serialization, form field generation, and validation for various data types. These types provide type-safe value handling and automatic conversion between Python objects and database storage.
3
4
## Capabilities
5
6
### Base Preference Type
7
8
Abstract base class that all preference types inherit from, providing common functionality for form field generation, serialization, and API representation.
9
10
```python { .api }
11
class BasePreferenceType(AbstractPreference):
12
"""
13
Base for all preference types.
14
15
Attributes:
16
- field_class: Form field class for display/editing
17
- serializer: Serializer class instance
18
- field_kwargs (dict): Additional form field kwargs
19
"""
20
field_class = None
21
serializer = None
22
field_kwargs = {}
23
24
@property
25
def initial(self):
26
"""Initial data for form field."""
27
28
@property
29
def field(self):
30
"""Form field instance with correct configuration."""
31
32
def get_initial(self):
33
"""Return initial value for form field."""
34
35
def setup_field(self, **kwargs):
36
"""Create configured form field."""
37
38
def get_field_kwargs(self) -> dict:
39
"""Return field instantiation kwargs."""
40
41
def api_repr(self, value):
42
"""Represent value for REST API."""
43
44
def get_api_additional_data(self) -> dict:
45
"""Additional API data."""
46
47
def get_api_field_data(self) -> dict:
48
"""Field data for API."""
49
50
def validate(self, value):
51
"""Custom validation logic."""
52
```
53
54
### Basic Data Types
55
56
Simple preference types for common data types with automatic form field generation.
57
58
```python { .api }
59
class BooleanPreference(BasePreferenceType):
60
"""
61
Stores boolean values.
62
63
Form Field: forms.BooleanField
64
Serializer: BooleanSerializer
65
"""
66
field_class = forms.BooleanField
67
serializer = BooleanSerializer()
68
69
class IntegerPreference(BasePreferenceType):
70
"""
71
Stores integer values.
72
73
Form Field: forms.IntegerField
74
Serializer: IntegerSerializer
75
Alias: IntPreference
76
"""
77
field_class = forms.IntegerField
78
serializer = IntegerSerializer()
79
80
# Alias for backward compatibility
81
IntPreference = IntegerPreference
82
83
class DecimalPreference(BasePreferenceType):
84
"""
85
Stores Decimal values.
86
87
Form Field: forms.DecimalField
88
Serializer: DecimalSerializer
89
"""
90
field_class = forms.DecimalField
91
serializer = DecimalSerializer()
92
93
class FloatPreference(BasePreferenceType):
94
"""
95
Stores float values.
96
97
Form Field: forms.FloatField
98
Serializer: FloatSerializer
99
"""
100
field_class = forms.FloatField
101
serializer = FloatSerializer()
102
103
class StringPreference(BasePreferenceType):
104
"""
105
Stores string values.
106
107
Form Field: forms.CharField
108
Serializer: StringSerializer
109
"""
110
field_class = forms.CharField
111
serializer = StringSerializer()
112
113
class LongStringPreference(StringPreference):
114
"""
115
String preference with textarea widget for longer text.
116
117
Form Field: forms.CharField with forms.Textarea widget
118
"""
119
widget = forms.Textarea
120
```
121
122
### Choice-Based Types
123
124
Preference types that allow selection from predefined options.
125
126
```python { .api }
127
class ChoicePreference(BasePreferenceType):
128
"""
129
String preference from list of choices.
130
131
Form Field: forms.ChoiceField
132
Serializer: StringSerializer
133
134
Attributes:
135
- choices (tuple): Available choices in Django choices format
136
"""
137
field_class = forms.ChoiceField
138
serializer = StringSerializer()
139
choices = ()
140
141
def get_choice_values(self) -> list:
142
"""Return list of valid choice values."""
143
144
def validate(self, value):
145
"""Validate value is in choices."""
146
147
class MultipleChoicePreference(ChoicePreference):
148
"""
149
Multiple strings from predefined choices.
150
151
Form Field: forms.MultipleChoiceField
152
Widget: forms.CheckboxSelectMultiple
153
Serializer: MultipleSerializer
154
"""
155
field_class = forms.MultipleChoiceField
156
widget = forms.CheckboxSelectMultiple
157
serializer = MultipleSerializer()
158
```
159
160
### Model-Related Types
161
162
Preference types for storing references to Django model instances.
163
164
```python { .api }
165
class ModelChoicePreference(BasePreferenceType):
166
"""
167
Reference to a Django model instance.
168
169
Form Field: forms.ModelChoiceField
170
Serializer: ModelSerializer
171
172
Attributes:
173
- model: Model class to reference
174
- queryset: Queryset to filter available instances
175
"""
176
field_class = forms.ModelChoiceField
177
serializer_class = ModelSerializer
178
model = None
179
queryset = None
180
181
class ModelMultipleChoicePreference(ModelChoicePreference):
182
"""
183
Multiple references to Django model instances.
184
185
Form Field: forms.ModelMultipleChoiceField
186
Serializer: ModelMultipleSerializer
187
"""
188
field_class = forms.ModelMultipleChoiceField
189
serializer_class = ModelMultipleSerializer
190
```
191
192
### File Upload Type
193
194
Preference type for handling file uploads with configurable storage.
195
196
```python { .api }
197
class FilePreference(BasePreferenceType):
198
"""
199
File upload reference with configurable storage.
200
201
Form Field: forms.FileField
202
Serializer: FileSerializer
203
"""
204
field_class = forms.FileField
205
serializer_class = FileSerializer
206
207
def get_upload_path(self) -> str:
208
"""Return upload path for files."""
209
210
def get_file_storage(self):
211
"""Return file storage backend."""
212
```
213
214
### Date/Time Types
215
216
Preference types for temporal data with timezone support.
217
218
```python { .api }
219
class DurationPreference(BasePreferenceType):
220
"""
221
Stores timedelta objects.
222
223
Form Field: forms.DurationField
224
Serializer: DurationSerializer
225
"""
226
field_class = forms.DurationField
227
serializer = DurationSerializer()
228
229
class DatePreference(BasePreferenceType):
230
"""
231
Stores date objects.
232
233
Form Field: forms.DateField
234
Serializer: DateSerializer
235
"""
236
field_class = forms.DateField
237
serializer = DateSerializer()
238
239
class DateTimePreference(BasePreferenceType):
240
"""
241
Stores datetime objects with timezone handling.
242
243
Form Field: forms.DateTimeField
244
Serializer: DateTimeSerializer
245
"""
246
field_class = forms.DateTimeField
247
serializer = DateTimeSerializer()
248
249
class TimePreference(BasePreferenceType):
250
"""
251
Stores time objects.
252
253
Form Field: forms.TimeField
254
Serializer: TimeSerializer
255
"""
256
field_class = forms.TimeField
257
serializer = TimeSerializer()
258
```
259
260
## Usage Examples
261
262
### Creating Custom Preference Types
263
264
```python
265
from dynamic_preferences.preferences import Section
266
from dynamic_preferences.types import StringPreference, ChoicePreference
267
from dynamic_preferences.registries import global_preferences_registry
268
269
# Define sections
270
general = Section('general')
271
ui = Section('ui')
272
273
# Basic string preference
274
@global_preferences_registry.register
275
class SiteTitle(StringPreference):
276
section = general
277
name = 'title'
278
default = 'My Site'
279
verbose_name = 'Site Title'
280
help_text = 'The title displayed in the site header'
281
282
# Choice preference
283
@global_preferences_registry.register
284
class Theme(ChoicePreference):
285
section = ui
286
name = 'theme'
287
default = 'light'
288
verbose_name = 'Site Theme'
289
choices = (
290
('light', 'Light Theme'),
291
('dark', 'Dark Theme'),
292
('auto', 'Auto (System)'),
293
)
294
295
# Model choice preference
296
from django.contrib.auth.models import User
297
298
@global_preferences_registry.register
299
class DefaultUser(ModelChoicePreference):
300
section = general
301
name = 'default_user'
302
model = User
303
queryset = User.objects.filter(is_active=True)
304
verbose_name = 'Default User'
305
```
306
307
### Using Preferences in Code
308
309
```python
310
from dynamic_preferences.registries import global_preferences_registry
311
312
def my_view(request):
313
global_preferences = global_preferences_registry.manager()
314
315
# Get typed values
316
site_title = global_preferences['general__title'] # str
317
theme = global_preferences['ui__theme'] # str from choices
318
default_user = global_preferences['general__default_user'] # User instance
319
320
return render(request, 'template.html', {
321
'site_title': site_title,
322
'theme': theme,
323
'default_user': default_user,
324
})
325
```
326
327
### Custom Validation
328
329
```python
330
from dynamic_preferences.types import StringPreference
331
from django.core.exceptions import ValidationError
332
333
@global_preferences_registry.register
334
class EmailAddress(StringPreference):
335
section = general
336
name = 'admin_email'
337
default = 'admin@example.com'
338
verbose_name = 'Admin Email'
339
340
def validate(self, value):
341
from django.core.validators import validate_email
342
try:
343
validate_email(value)
344
except ValidationError:
345
raise ValidationError('Please enter a valid email address')
346
```