CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-dynamic-preferences

Dynamic global and instance settings for your django project

Pending
Overview
Eval results
Files

admin-integration.mddocs/

Django Admin Integration

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.

Capabilities

Dynamic Preference Admin

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)
        """

Global Preference Admin

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 = GlobalSinglePreferenceForm

Per Instance Preference Admin

Base 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."""

Section Filter

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
        """

Usage Examples

Basic Admin Registration

# 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)

Custom Admin Class

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)

User Preference Admin

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'

Inline Admin for Related Models

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)

Custom Form Integration

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 form

Bulk Actions

class 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'

Advanced Filtering

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

docs

admin-integration.md

core-models.md

django-integration.md

forms-views.md

index.md

preference-types.md

registries.md

rest-api.md

serialization.md

signals.md

user-preferences.md

tile.json