Dynamic global and instance settings for your django project
—
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.
Abstract base class that all preference types inherit from, providing common functionality for form field generation, serialization, and API representation.
class BasePreferenceType(AbstractPreference):
"""
Base for all preference types.
Attributes:
- field_class: Form field class for display/editing
- serializer: Serializer class instance
- field_kwargs (dict): Additional form field kwargs
"""
field_class = None
serializer = None
field_kwargs = {}
@property
def initial(self):
"""Initial data for form field."""
@property
def field(self):
"""Form field instance with correct configuration."""
def get_initial(self):
"""Return initial value for form field."""
def setup_field(self, **kwargs):
"""Create configured form field."""
def get_field_kwargs(self) -> dict:
"""Return field instantiation kwargs."""
def api_repr(self, value):
"""Represent value for REST API."""
def get_api_additional_data(self) -> dict:
"""Additional API data."""
def get_api_field_data(self) -> dict:
"""Field data for API."""
def validate(self, value):
"""Custom validation logic."""Simple preference types for common data types with automatic form field generation.
class BooleanPreference(BasePreferenceType):
"""
Stores boolean values.
Form Field: forms.BooleanField
Serializer: BooleanSerializer
"""
field_class = forms.BooleanField
serializer = BooleanSerializer()
class IntegerPreference(BasePreferenceType):
"""
Stores integer values.
Form Field: forms.IntegerField
Serializer: IntegerSerializer
Alias: IntPreference
"""
field_class = forms.IntegerField
serializer = IntegerSerializer()
# Alias for backward compatibility
IntPreference = IntegerPreference
class DecimalPreference(BasePreferenceType):
"""
Stores Decimal values.
Form Field: forms.DecimalField
Serializer: DecimalSerializer
"""
field_class = forms.DecimalField
serializer = DecimalSerializer()
class FloatPreference(BasePreferenceType):
"""
Stores float values.
Form Field: forms.FloatField
Serializer: FloatSerializer
"""
field_class = forms.FloatField
serializer = FloatSerializer()
class StringPreference(BasePreferenceType):
"""
Stores string values.
Form Field: forms.CharField
Serializer: StringSerializer
"""
field_class = forms.CharField
serializer = StringSerializer()
class LongStringPreference(StringPreference):
"""
String preference with textarea widget for longer text.
Form Field: forms.CharField with forms.Textarea widget
"""
widget = forms.TextareaPreference types that allow selection from predefined options.
class ChoicePreference(BasePreferenceType):
"""
String preference from list of choices.
Form Field: forms.ChoiceField
Serializer: StringSerializer
Attributes:
- choices (tuple): Available choices in Django choices format
"""
field_class = forms.ChoiceField
serializer = StringSerializer()
choices = ()
def get_choice_values(self) -> list:
"""Return list of valid choice values."""
def validate(self, value):
"""Validate value is in choices."""
class MultipleChoicePreference(ChoicePreference):
"""
Multiple strings from predefined choices.
Form Field: forms.MultipleChoiceField
Widget: forms.CheckboxSelectMultiple
Serializer: MultipleSerializer
"""
field_class = forms.MultipleChoiceField
widget = forms.CheckboxSelectMultiple
serializer = MultipleSerializer()Preference types for storing references to Django model instances.
class ModelChoicePreference(BasePreferenceType):
"""
Reference to a Django model instance.
Form Field: forms.ModelChoiceField
Serializer: ModelSerializer
Attributes:
- model: Model class to reference
- queryset: Queryset to filter available instances
"""
field_class = forms.ModelChoiceField
serializer_class = ModelSerializer
model = None
queryset = None
class ModelMultipleChoicePreference(ModelChoicePreference):
"""
Multiple references to Django model instances.
Form Field: forms.ModelMultipleChoiceField
Serializer: ModelMultipleSerializer
"""
field_class = forms.ModelMultipleChoiceField
serializer_class = ModelMultipleSerializerPreference type for handling file uploads with configurable storage.
class FilePreference(BasePreferenceType):
"""
File upload reference with configurable storage.
Form Field: forms.FileField
Serializer: FileSerializer
"""
field_class = forms.FileField
serializer_class = FileSerializer
def get_upload_path(self) -> str:
"""Return upload path for files."""
def get_file_storage(self):
"""Return file storage backend."""Preference types for temporal data with timezone support.
class DurationPreference(BasePreferenceType):
"""
Stores timedelta objects.
Form Field: forms.DurationField
Serializer: DurationSerializer
"""
field_class = forms.DurationField
serializer = DurationSerializer()
class DatePreference(BasePreferenceType):
"""
Stores date objects.
Form Field: forms.DateField
Serializer: DateSerializer
"""
field_class = forms.DateField
serializer = DateSerializer()
class DateTimePreference(BasePreferenceType):
"""
Stores datetime objects with timezone handling.
Form Field: forms.DateTimeField
Serializer: DateTimeSerializer
"""
field_class = forms.DateTimeField
serializer = DateTimeSerializer()
class TimePreference(BasePreferenceType):
"""
Stores time objects.
Form Field: forms.TimeField
Serializer: TimeSerializer
"""
field_class = forms.TimeField
serializer = TimeSerializer()from dynamic_preferences.preferences import Section
from dynamic_preferences.types import StringPreference, ChoicePreference
from dynamic_preferences.registries import global_preferences_registry
# Define sections
general = Section('general')
ui = Section('ui')
# Basic string preference
@global_preferences_registry.register
class SiteTitle(StringPreference):
section = general
name = 'title'
default = 'My Site'
verbose_name = 'Site Title'
help_text = 'The title displayed in the site header'
# Choice preference
@global_preferences_registry.register
class Theme(ChoicePreference):
section = ui
name = 'theme'
default = 'light'
verbose_name = 'Site Theme'
choices = (
('light', 'Light Theme'),
('dark', 'Dark Theme'),
('auto', 'Auto (System)'),
)
# Model choice preference
from django.contrib.auth.models import User
@global_preferences_registry.register
class DefaultUser(ModelChoicePreference):
section = general
name = 'default_user'
model = User
queryset = User.objects.filter(is_active=True)
verbose_name = 'Default User'from dynamic_preferences.registries import global_preferences_registry
def my_view(request):
global_preferences = global_preferences_registry.manager()
# Get typed values
site_title = global_preferences['general__title'] # str
theme = global_preferences['ui__theme'] # str from choices
default_user = global_preferences['general__default_user'] # User instance
return render(request, 'template.html', {
'site_title': site_title,
'theme': theme,
'default_user': default_user,
})from dynamic_preferences.types import StringPreference
from django.core.exceptions import ValidationError
@global_preferences_registry.register
class EmailAddress(StringPreference):
section = general
name = 'admin_email'
default = 'admin@example.com'
verbose_name = 'Admin Email'
def validate(self, value):
from django.core.validators import validate_email
try:
validate_email(value)
except ValidationError:
raise ValidationError('Please enter a valid email address')Install with Tessl CLI
npx tessl i tessl/pypi-django-dynamic-preferences