Dynamic global and instance settings for your django project
—
Complete Django admin interface integration with custom admin classes, forms, and filters for preference management. This provides a user-friendly web interface for managing preferences through Django's built-in admin system.
Base admin class for preference models with customized display, filtering, and editing capabilities.
class DynamicPreferenceAdmin(admin.ModelAdmin):
"""
Base admin class for preference models.
Attributes:
- list_display: Shows verbose_name, name, section_name, help_text, raw_value, default_value
- readonly_fields: name, section_name, default_value
- search_fields: name, section, raw_value
- list_filter: section (with SectionFilter)
"""
list_display = ('verbose_name', 'name', 'section_name', 'help_text', 'raw_value', 'default_value')
readonly_fields = ('name', 'section_name', 'default_value')
search_fields = ('name', 'section', 'raw_value')
list_filter = ('section',)
def default_value(self, obj):
"""
Display the default value for the preference.
Args:
- obj: Preference model instance
Returns:
String representation of default value
"""
def section_name(self, obj):
"""
Display the section verbose name.
Args:
- obj: Preference model instance
Returns:
Section verbose name or section name
"""
def save_model(self, request, obj, form, change):
"""
Handle preference updates through preference manager.
Args:
- request: HTTP request
- obj: Preference model instance
- form: Admin form
- change: Whether this is an update (True) or create (False)
"""Admin class specifically for global preferences with appropriate form configuration.
class GlobalPreferenceAdmin(DynamicPreferenceAdmin):
"""
Admin class for global preferences.
Attributes:
- form: GlobalSinglePreferenceForm
- changelist_form: GlobalSinglePreferenceForm
"""
form = GlobalSinglePreferenceForm
changelist_form = GlobalSinglePreferenceFormBase admin class for per-instance preferences with instance field management.
class PerInstancePreferenceAdmin(DynamicPreferenceAdmin):
"""
Base admin class for per-instance preferences.
Attributes:
- list_display: Adds "instance" to parent list_display
- fields: Adds "instance" to parent fields
- raw_id_fields: ("instance",) for better performance with large datasets
- form: SinglePerInstancePreferenceForm
"""
raw_id_fields = ('instance',)
form = SinglePerInstancePreferenceForm
def get_list_display(self, request):
"""Add instance to list display."""
def get_fields(self, request, obj=None):
"""Add instance to form fields."""Custom admin list filter for filtering preferences by section with user-friendly section names.
class SectionFilter(admin.SimpleListFilter):
"""
Admin list filter for preference sections.
Displays section verbose names when available,
falling back to section names for better UX.
"""
title = 'section'
parameter_name = 'section'
def lookups(self, request, model_admin):
"""
Return list of section choices for filtering.
Returns:
List of tuples (section_name, section_display_name)
"""
def queryset(self, request, queryset):
"""
Filter queryset by selected section.
Args:
- request: HTTP request
- queryset: Base queryset
Returns:
Filtered queryset
"""# admin.py
from django.contrib import admin
from dynamic_preferences.admin import GlobalPreferenceAdmin
from dynamic_preferences.models import GlobalPreferenceModel
# Register global preferences with custom admin
admin.site.register(GlobalPreferenceModel, GlobalPreferenceAdmin)from dynamic_preferences.admin import DynamicPreferenceAdmin
from myapp.models import MyPreferenceModel
class MyPreferenceAdmin(DynamicPreferenceAdmin):
# Customize list display
list_display = DynamicPreferenceAdmin.list_display + ('custom_field',)
# Add custom filtering
list_filter = DynamicPreferenceAdmin.list_filter + ('custom_field',)
# Add custom search fields
search_fields = DynamicPreferenceAdmin.search_fields + ('custom_field',)
def custom_field(self, obj):
"""Custom field display method."""
return obj.some_custom_logic()
custom_field.short_description = 'Custom Field'
admin.site.register(MyPreferenceModel, MyPreferenceAdmin)from dynamic_preferences.users.admin import UserPreferenceAdmin
from dynamic_preferences.users.models import UserPreferenceModel
# The UserPreferenceAdmin is already configured for user preferences
admin.site.register(UserPreferenceModel, UserPreferenceAdmin)
# Custom user preference admin
class CustomUserPreferenceAdmin(UserPreferenceAdmin):
# Show username in list display
list_display = UserPreferenceAdmin.list_display + ('get_username',)
# Filter by user groups
list_filter = UserPreferenceAdmin.list_filter + ('instance__groups',)
def get_username(self, obj):
"""Display username for the preference."""
return obj.instance.username if obj.instance else 'N/A'
get_username.short_description = 'Username'
get_username.admin_order_field = 'instance__username'from django.contrib import admin
from dynamic_preferences.admin import PerInstancePreferenceAdmin
class PreferenceInline(admin.TabularInline):
"""Inline admin for preferences on related model admin."""
model = MyPreferenceModel
extra = 0
readonly_fields = ('name', 'section', 'default_value')
fields = ('name', 'section', 'value', 'default_value')
class MyModelAdmin(admin.ModelAdmin):
inlines = [PreferenceInline]
admin.site.register(MyModel, MyModelAdmin)from dynamic_preferences.admin import DynamicPreferenceAdmin
from dynamic_preferences.forms import GlobalSinglePreferenceForm
class CustomPreferenceForm(GlobalSinglePreferenceForm):
"""Custom form with additional validation."""
def clean(self):
cleaned_data = super().clean()
# Add custom validation logic
if self.preference and self.preference.name == 'sensitive_setting':
if not self.request.user.is_superuser:
raise ValidationError('Only superusers can modify this setting')
return cleaned_data
class CustomPreferenceAdmin(DynamicPreferenceAdmin):
form = CustomPreferenceForm
def get_form(self, request, obj=None, **kwargs):
"""Pass request to form for user-based validation."""
form = super().get_form(request, obj, **kwargs)
form.request = request
return formclass BulkPreferenceAdmin(DynamicPreferenceAdmin):
"""Admin with bulk actions for preference management."""
actions = ['reset_to_default', 'mark_as_configured']
def reset_to_default(self, request, queryset):
"""Reset selected preferences to their default values."""
count = 0
for pref in queryset:
if pref.preference:
pref.value = pref.preference.default
pref.save()
count += 1
self.message_user(
request,
f'Successfully reset {count} preferences to default values.'
)
reset_to_default.short_description = 'Reset selected preferences to default'
def mark_as_configured(self, request, queryset):
"""Custom bulk action example."""
# Custom logic here
pass
mark_as_configured.short_description = 'Mark as configured'class AdvancedSectionFilter(admin.SimpleListFilter):
"""Advanced section filter with grouping."""
title = 'section group'
parameter_name = 'section_group'
def lookups(self, request, model_admin):
sections = set()
for pref in model_admin.model.objects.all():
if pref.section:
# Group sections by prefix
section_group = pref.section.split('_')[0] if '_' in pref.section else pref.section
sections.add(section_group)
return [(group, group.title()) for group in sorted(sections)]
def queryset(self, request, queryset):
if self.value():
return queryset.filter(section__startswith=self.value())
return queryset
class AdvancedPreferenceAdmin(DynamicPreferenceAdmin):
list_filter = DynamicPreferenceAdmin.list_filter + (AdvancedSectionFilter,)Install with Tessl CLI
npx tessl i tessl/pypi-django-dynamic-preferences