or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

admin-integration.mdcore-models.mddjango-integration.mdforms-views.mdindex.mdpreference-types.mdregistries.mdrest-api.mdserialization.mdsignals.mduser-preferences.md

admin-integration.mddocs/

0

# Django Admin Integration

1

2

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.

3

4

## Capabilities

5

6

### Dynamic Preference Admin

7

8

Base admin class for preference models with customized display, filtering, and editing capabilities.

9

10

```python { .api }

11

class DynamicPreferenceAdmin(admin.ModelAdmin):

12

"""

13

Base admin class for preference models.

14

15

Attributes:

16

- list_display: Shows verbose_name, name, section_name, help_text, raw_value, default_value

17

- readonly_fields: name, section_name, default_value

18

- search_fields: name, section, raw_value

19

- list_filter: section (with SectionFilter)

20

"""

21

list_display = ('verbose_name', 'name', 'section_name', 'help_text', 'raw_value', 'default_value')

22

readonly_fields = ('name', 'section_name', 'default_value')

23

search_fields = ('name', 'section', 'raw_value')

24

list_filter = ('section',)

25

26

def default_value(self, obj):

27

"""

28

Display the default value for the preference.

29

30

Args:

31

- obj: Preference model instance

32

33

Returns:

34

String representation of default value

35

"""

36

37

def section_name(self, obj):

38

"""

39

Display the section verbose name.

40

41

Args:

42

- obj: Preference model instance

43

44

Returns:

45

Section verbose name or section name

46

"""

47

48

def save_model(self, request, obj, form, change):

49

"""

50

Handle preference updates through preference manager.

51

52

Args:

53

- request: HTTP request

54

- obj: Preference model instance

55

- form: Admin form

56

- change: Whether this is an update (True) or create (False)

57

"""

58

```

59

60

### Global Preference Admin

61

62

Admin class specifically for global preferences with appropriate form configuration.

63

64

```python { .api }

65

class GlobalPreferenceAdmin(DynamicPreferenceAdmin):

66

"""

67

Admin class for global preferences.

68

69

Attributes:

70

- form: GlobalSinglePreferenceForm

71

- changelist_form: GlobalSinglePreferenceForm

72

"""

73

form = GlobalSinglePreferenceForm

74

changelist_form = GlobalSinglePreferenceForm

75

```

76

77

### Per Instance Preference Admin

78

79

Base admin class for per-instance preferences with instance field management.

80

81

```python { .api }

82

class PerInstancePreferenceAdmin(DynamicPreferenceAdmin):

83

"""

84

Base admin class for per-instance preferences.

85

86

Attributes:

87

- list_display: Adds "instance" to parent list_display

88

- fields: Adds "instance" to parent fields

89

- raw_id_fields: ("instance",) for better performance with large datasets

90

- form: SinglePerInstancePreferenceForm

91

"""

92

raw_id_fields = ('instance',)

93

form = SinglePerInstancePreferenceForm

94

95

def get_list_display(self, request):

96

"""Add instance to list display."""

97

98

def get_fields(self, request, obj=None):

99

"""Add instance to form fields."""

100

```

101

102

### Section Filter

103

104

Custom admin list filter for filtering preferences by section with user-friendly section names.

105

106

```python { .api }

107

class SectionFilter(admin.SimpleListFilter):

108

"""

109

Admin list filter for preference sections.

110

111

Displays section verbose names when available,

112

falling back to section names for better UX.

113

"""

114

title = 'section'

115

parameter_name = 'section'

116

117

def lookups(self, request, model_admin):

118

"""

119

Return list of section choices for filtering.

120

121

Returns:

122

List of tuples (section_name, section_display_name)

123

"""

124

125

def queryset(self, request, queryset):

126

"""

127

Filter queryset by selected section.

128

129

Args:

130

- request: HTTP request

131

- queryset: Base queryset

132

133

Returns:

134

Filtered queryset

135

"""

136

```

137

138

## Usage Examples

139

140

### Basic Admin Registration

141

142

```python

143

# admin.py

144

from django.contrib import admin

145

from dynamic_preferences.admin import GlobalPreferenceAdmin

146

from dynamic_preferences.models import GlobalPreferenceModel

147

148

# Register global preferences with custom admin

149

admin.site.register(GlobalPreferenceModel, GlobalPreferenceAdmin)

150

```

151

152

### Custom Admin Class

153

154

```python

155

from dynamic_preferences.admin import DynamicPreferenceAdmin

156

from myapp.models import MyPreferenceModel

157

158

class MyPreferenceAdmin(DynamicPreferenceAdmin):

159

# Customize list display

160

list_display = DynamicPreferenceAdmin.list_display + ('custom_field',)

161

162

# Add custom filtering

163

list_filter = DynamicPreferenceAdmin.list_filter + ('custom_field',)

164

165

# Add custom search fields

166

search_fields = DynamicPreferenceAdmin.search_fields + ('custom_field',)

167

168

def custom_field(self, obj):

169

"""Custom field display method."""

170

return obj.some_custom_logic()

171

custom_field.short_description = 'Custom Field'

172

173

admin.site.register(MyPreferenceModel, MyPreferenceAdmin)

174

```

175

176

### User Preference Admin

177

178

```python

179

from dynamic_preferences.users.admin import UserPreferenceAdmin

180

from dynamic_preferences.users.models import UserPreferenceModel

181

182

# The UserPreferenceAdmin is already configured for user preferences

183

admin.site.register(UserPreferenceModel, UserPreferenceAdmin)

184

185

# Custom user preference admin

186

class CustomUserPreferenceAdmin(UserPreferenceAdmin):

187

# Show username in list display

188

list_display = UserPreferenceAdmin.list_display + ('get_username',)

189

190

# Filter by user groups

191

list_filter = UserPreferenceAdmin.list_filter + ('instance__groups',)

192

193

def get_username(self, obj):

194

"""Display username for the preference."""

195

return obj.instance.username if obj.instance else 'N/A'

196

get_username.short_description = 'Username'

197

get_username.admin_order_field = 'instance__username'

198

```

199

200

### Inline Admin for Related Models

201

202

```python

203

from django.contrib import admin

204

from dynamic_preferences.admin import PerInstancePreferenceAdmin

205

206

class PreferenceInline(admin.TabularInline):

207

"""Inline admin for preferences on related model admin."""

208

model = MyPreferenceModel

209

extra = 0

210

readonly_fields = ('name', 'section', 'default_value')

211

fields = ('name', 'section', 'value', 'default_value')

212

213

class MyModelAdmin(admin.ModelAdmin):

214

inlines = [PreferenceInline]

215

216

admin.site.register(MyModel, MyModelAdmin)

217

```

218

219

### Custom Form Integration

220

221

```python

222

from dynamic_preferences.admin import DynamicPreferenceAdmin

223

from dynamic_preferences.forms import GlobalSinglePreferenceForm

224

225

class CustomPreferenceForm(GlobalSinglePreferenceForm):

226

"""Custom form with additional validation."""

227

228

def clean(self):

229

cleaned_data = super().clean()

230

# Add custom validation logic

231

if self.preference and self.preference.name == 'sensitive_setting':

232

if not self.request.user.is_superuser:

233

raise ValidationError('Only superusers can modify this setting')

234

return cleaned_data

235

236

class CustomPreferenceAdmin(DynamicPreferenceAdmin):

237

form = CustomPreferenceForm

238

239

def get_form(self, request, obj=None, **kwargs):

240

"""Pass request to form for user-based validation."""

241

form = super().get_form(request, obj, **kwargs)

242

form.request = request

243

return form

244

```

245

246

### Bulk Actions

247

248

```python

249

class BulkPreferenceAdmin(DynamicPreferenceAdmin):

250

"""Admin with bulk actions for preference management."""

251

252

actions = ['reset_to_default', 'mark_as_configured']

253

254

def reset_to_default(self, request, queryset):

255

"""Reset selected preferences to their default values."""

256

count = 0

257

for pref in queryset:

258

if pref.preference:

259

pref.value = pref.preference.default

260

pref.save()

261

count += 1

262

263

self.message_user(

264

request,

265

f'Successfully reset {count} preferences to default values.'

266

)

267

reset_to_default.short_description = 'Reset selected preferences to default'

268

269

def mark_as_configured(self, request, queryset):

270

"""Custom bulk action example."""

271

# Custom logic here

272

pass

273

mark_as_configured.short_description = 'Mark as configured'

274

```

275

276

### Advanced Filtering

277

278

```python

279

class AdvancedSectionFilter(admin.SimpleListFilter):

280

"""Advanced section filter with grouping."""

281

title = 'section group'

282

parameter_name = 'section_group'

283

284

def lookups(self, request, model_admin):

285

sections = set()

286

for pref in model_admin.model.objects.all():

287

if pref.section:

288

# Group sections by prefix

289

section_group = pref.section.split('_')[0] if '_' in pref.section else pref.section

290

sections.add(section_group)

291

292

return [(group, group.title()) for group in sorted(sections)]

293

294

def queryset(self, request, queryset):

295

if self.value():

296

return queryset.filter(section__startswith=self.value())

297

return queryset

298

299

class AdvancedPreferenceAdmin(DynamicPreferenceAdmin):

300

list_filter = DynamicPreferenceAdmin.list_filter + (AdvancedSectionFilter,)

301

```