or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

admin.mdconfiguration.mdfields.mdindex.mdmodels.mdtemplate-utils.md

admin.mddocs/

0

# Admin Interface

1

2

Django Filer provides a comprehensive admin interface with file browser, drag-and-drop uploads, folder navigation, and custom widgets for model fields. The admin interface is automatically registered and provides rich functionality for file management.

3

4

## Capabilities

5

6

### Auto-Registered Admin Classes

7

8

Django Filer automatically registers admin interfaces for all core models, providing full CRUD functionality with specialized features for file management.

9

10

```python { .api }

11

class FileAdmin(admin.ModelAdmin):

12

"""

13

Admin interface for File model with specialized file management features.

14

15

Features:

16

- File preview and thumbnail display

17

- Drag-and-drop upload support

18

- Bulk operations (move, delete, change permissions)

19

- Advanced search and filtering

20

- Permission checking integration

21

"""

22

23

class FolderAdmin(admin.ModelAdmin):

24

"""

25

Admin interface for Folder model with hierarchical navigation.

26

27

Features:

28

- Tree-based folder navigation

29

- Drag-and-drop folder organization

30

- Permission management interface

31

- Bulk folder operations

32

"""

33

34

class ImageAdmin(FileAdmin):

35

"""

36

Admin interface for Image model extending FileAdmin.

37

38

Additional Features:

39

- Image preview with dimensions

40

- EXIF data display

41

- Thumbnail generation controls

42

- Subject location editing

43

"""

44

45

class ClipboardAdmin(admin.ModelAdmin):

46

"""Admin interface for Clipboard model."""

47

48

class PermissionAdmin(admin.ModelAdmin):

49

"""Admin interface for FolderPermission model."""

50

51

class ThumbnailOptionAdmin(admin.ModelAdmin):

52

"""Admin interface for ThumbnailOption model."""

53

```

54

55

### Custom Admin Widgets

56

57

Specialized widgets for integrating filer objects into other model admin interfaces.

58

59

```python { .api }

60

class AdminFileWidget(ForeignKeyRawIdWidget):

61

"""

62

Admin widget for file selection with popup browser.

63

64

Features:

65

- Popup file browser with folder navigation

66

- File preview and metadata display

67

- Search and filter capabilities

68

- Drag-and-drop file upload in popup

69

"""

70

71

def render(self, name, value, attrs=None, renderer=None):

72

"""

73

Render widget HTML with file browser popup.

74

75

Args:

76

name (str): Field name

77

value: Current field value (File ID)

78

attrs (dict): HTML attributes

79

renderer: Template renderer

80

81

Returns:

82

str: Rendered HTML with popup trigger and preview

83

"""

84

85

def label_for_value(self, value):

86

"""

87

Get display label for selected file.

88

89

Args:

90

value: File ID

91

92

Returns:

93

str: HTML label with file name and preview

94

"""

95

96

def obj_for_value(self, value):

97

"""

98

Get File object for given ID.

99

100

Args:

101

value: File ID

102

103

Returns:

104

File or None: File object if exists

105

"""

106

107

class Media:

108

"""CSS and JavaScript requirements for the widget."""

109

css = {

110

'all': (

111

'filer/css/admin_filer.css',

112

# Icon CSS library

113

)

114

}

115

js = (

116

'admin/js/vendor/jquery/jquery.min.js',

117

'admin/js/jquery.init.js',

118

'filer/js/libs/dropzone.min.js',

119

'filer/js/addons/dropzone.init.js',

120

'filer/js/addons/popup_handling.js',

121

'filer/js/addons/widget.js',

122

)

123

124

class AdminImageWidget(AdminFileWidget):

125

"""

126

Admin widget for image selection extending AdminFileWidget.

127

128

Additional Features:

129

- Image thumbnail preview

130

- Image-specific metadata display

131

- Dimension information

132

"""

133

134

class AdminFolderWidget(ForeignKeyRawIdWidget):

135

"""

136

Admin widget for folder selection with folder browser.

137

138

Features:

139

- Hierarchical folder tree popup

140

- Folder creation capabilities

141

- Permission-aware folder filtering

142

- Breadcrumb navigation

143

"""

144

145

def render(self, name, value, attrs=None, renderer=None):

146

"""

147

Render widget HTML with folder browser popup.

148

149

Args:

150

name (str): Field name

151

value: Current field value (Folder ID)

152

attrs (dict): HTML attributes

153

renderer: Template renderer

154

155

Returns:

156

str: Rendered HTML with folder browser popup

157

"""

158

159

class Media:

160

"""CSS and JavaScript requirements."""

161

css = {"all": ('filer/css/admin_filer.css',)}

162

js = ('filer/js/addons/popup_handling.js',)

163

```

164

165

### Admin Form Fields

166

167

Specialized form fields that work with the admin widgets to provide rich functionality.

168

169

```python { .api }

170

class AdminFileFormField(forms.ModelChoiceField):

171

"""

172

Form field for file selection in admin interface.

173

174

Integrates with AdminFileWidget to provide:

175

- File browser popup

176

- Search and filtering

177

- Permission-aware file selection

178

"""

179

180

def __init__(self, rel, queryset, to_field_name, *args, **kwargs):

181

"""

182

Initialize form field with admin widget.

183

184

Args:

185

rel: Field relation object

186

queryset: Available files QuerySet

187

to_field_name: Target field name

188

"""

189

190

class AdminImageFormField(AdminFileFormField):

191

"""Form field for image selection extending AdminFileFormField."""

192

193

class AdminFolderFormField(forms.ModelChoiceField):

194

"""

195

Form field for folder selection in admin interface.

196

197

Integrates with AdminFolderWidget to provide:

198

- Folder tree popup

199

- Permission-aware folder selection

200

- Folder creation capabilities

201

"""

202

```

203

204

### Directory Listing and File Browser

205

206

Core admin views providing the file browser interface used throughout the admin.

207

208

```python { .api }

209

# Admin URL patterns (internal)

210

urlpatterns = [

211

path('admin:filer-directory_listing-last', DirectoryListingView.as_view()),

212

path('admin:filer-directory_listing-unfiled_images', UnfiledImagesView.as_view()),

213

path('admin:filer-directory_listing-images_with_missing_data', ImagesWithMissingDataView.as_view()),

214

]

215

216

class DirectoryListingView:

217

"""

218

Main file browser view providing:

219

- Folder navigation with breadcrumbs

220

- File and folder listing with previews

221

- Drag-and-drop upload

222

- Bulk operations (move, delete, permissions)

223

- Search and filtering

224

- Permission checking

225

"""

226

227

class FilePickerView:

228

"""

229

File selection popup view for widgets providing:

230

- Modal file browser

231

- File selection and confirmation

232

- Upload capabilities within popup

233

"""

234

```

235

236

## Usage Examples

237

238

### Using Admin Widgets in Custom Admin

239

240

```python

241

from django.contrib import admin

242

from filer.fields import FilerFileField, FilerImageField

243

from .models import Article

244

245

class ArticleAdmin(admin.ModelAdmin):

246

list_display = ['title', 'created_at', 'featured_image_preview']

247

list_filter = ['created_at']

248

search_fields = ['title', 'content']

249

250

# Organize fields in fieldsets

251

fieldsets = (

252

('Content', {

253

'fields': ('title', 'content', 'author')

254

}),

255

('Media', {

256

'fields': ('featured_image', 'attachment', 'gallery_folder'),

257

'classes': ('collapse',), # Collapsible section

258

}),

259

('Metadata', {

260

'fields': ('created_at', 'updated_at'),

261

'classes': ('collapse',),

262

}),

263

)

264

265

readonly_fields = ['created_at', 'updated_at']

266

267

def featured_image_preview(self, obj):

268

"""Show image preview in list view."""

269

if obj.featured_image:

270

return f'<img src="{obj.featured_image.icons["32"]}" alt="Preview" />'

271

return "No image"

272

featured_image_preview.allow_tags = True

273

featured_image_preview.short_description = "Preview"

274

275

admin.site.register(Article, ArticleAdmin)

276

```

277

278

### Customizing Widget Behavior

279

280

```python

281

from django import forms

282

from filer.fields import FilerImageField

283

from filer.models import Image

284

285

class CustomArticleForm(forms.ModelForm):

286

# Override widget for more control

287

featured_image = forms.ModelChoiceField(

288

queryset=Image.objects.filter(is_public=True),

289

widget=AdminImageWidget(rel=FilerImageField().remote_field),

290

required=False

291

)

292

293

class Meta:

294

model = Article

295

fields = '__all__'

296

297

def __init__(self, *args, **kwargs):

298

super().__init__(*args, **kwargs)

299

300

# Customize widget attributes

301

self.fields['featured_image'].widget.attrs.update({

302

'class': 'custom-image-widget',

303

'data-placeholder': 'Select an image...'

304

})

305

306

class ArticleAdmin(admin.ModelAdmin):

307

form = CustomArticleForm

308

```

309

310

### Bulk Operations in File Admin

311

312

```python

313

from django.contrib import admin

314

from filer.models import File

315

316

class CustomFileAdmin(admin.ModelAdmin):

317

list_display = ['name', 'folder', 'owner', 'is_public', 'file_size']

318

list_filter = ['is_public', 'folder', 'mime_type']

319

search_fields = ['name', 'original_filename']

320

321

# Enable bulk operations

322

actions = ['make_public', 'make_private', 'move_to_folder']

323

324

def make_public(self, request, queryset):

325

"""Bulk action to make files public."""

326

updated = queryset.update(is_public=True)

327

self.message_user(request, f'{updated} files made public.')

328

make_public.short_description = "Make selected files public"

329

330

def make_private(self, request, queryset):

331

"""Bulk action to make files private."""

332

updated = queryset.update(is_public=False)

333

self.message_user(request, f'{updated} files made private.')

334

make_private.short_description = "Make selected files private"

335

336

def move_to_folder(self, request, queryset):

337

"""Bulk action to move files to a folder."""

338

# Custom logic for folder selection and moving

339

pass

340

move_to_folder.short_description = "Move selected files to folder"

341

342

# Unregister default and register custom

343

admin.site.unregister(File)

344

admin.site.register(File, CustomFileAdmin)

345

```

346

347

### Custom File Upload Handling

348

349

```python

350

from django.contrib import admin

351

from django.urls import path

352

from django.http import JsonResponse

353

from filer.models import File, Folder

354

355

class CustomFilerAdmin(admin.ModelAdmin):

356

def get_urls(self):

357

"""Add custom upload endpoint."""

358

urls = super().get_urls()

359

custom_urls = [

360

path('bulk-upload/', self.admin_site.admin_view(self.bulk_upload_view),

361

name='filer_file_bulk_upload'),

362

]

363

return custom_urls + urls

364

365

def bulk_upload_view(self, request):

366

"""Custom bulk upload handler."""

367

if request.method == 'POST':

368

files = request.FILES.getlist('files')

369

folder_id = request.POST.get('folder_id')

370

371

folder = None

372

if folder_id:

373

folder = Folder.objects.get(pk=folder_id)

374

375

uploaded_files = []

376

for file in files:

377

file_obj = File.objects.create(

378

file=file,

379

name=file.name,

380

folder=folder,

381

owner=request.user

382

)

383

uploaded_files.append({

384

'id': file_obj.id,

385

'name': file_obj.name,

386

'url': file_obj.url

387

})

388

389

return JsonResponse({

390

'success': True,

391

'files': uploaded_files

392

})

393

394

return JsonResponse({'success': False})

395

```

396

397

### Permission-Aware Admin Views

398

399

```python

400

from django.contrib import admin

401

from filer.models import File, Folder

402

403

class PermissionAwareFileAdmin(admin.ModelAdmin):

404

def get_queryset(self, request):

405

"""Filter files based on user permissions."""

406

qs = super().get_queryset(request)

407

408

if request.user.is_superuser:

409

return qs

410

411

# Filter files user has read permission for

412

allowed_files = []

413

for file in qs:

414

if file.has_read_permission(request.user):

415

allowed_files.append(file.pk)

416

417

return qs.filter(pk__in=allowed_files)

418

419

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

420

"""Check edit permission for specific file."""

421

if obj is None:

422

return True # Allow viewing list

423

424

return obj.has_edit_permission(request.user)

425

426

class PermissionAwareFolderAdmin(admin.ModelAdmin):

427

def get_queryset(self, request):

428

"""Filter folders based on user permissions."""

429

qs = super().get_queryset(request)

430

431

if request.user.is_superuser:

432

return qs

433

434

# Filter folders user has read permission for

435

allowed_folders = []

436

for folder in qs:

437

if folder.has_read_permission(request.user):

438

allowed_folders.append(folder.pk)

439

440

return qs.filter(pk__in=allowed_folders)

441

```

442

443

### Customizing File Display

444

445

```python

446

from django.contrib import admin

447

from django.utils.html import format_html

448

from filer.models import File, Image

449

450

class RichFileAdmin(admin.ModelAdmin):

451

list_display = [

452

'file_preview', 'name', 'folder', 'size_formatted',

453

'mime_type', 'is_public', 'uploaded_at'

454

]

455

456

def file_preview(self, obj):

457

"""Show file preview or icon."""

458

if hasattr(obj, 'icons') and obj.icons:

459

# For images, show thumbnail

460

return format_html(

461

'<img src="{}" alt="{}" style="max-width: 48px; max-height: 48px;" />',

462

obj.icons.get('48', obj.icons.get('32', '')),

463

obj.name

464

)

465

else:

466

# For other files, show type icon

467

return format_html(

468

'<span class="filer-file-icon filer-file-icon-{}" title="{}"></span>',

469

obj.extension or 'unknown',

470

obj.mime_type

471

)

472

file_preview.short_description = "Preview"

473

474

def size_formatted(self, obj):

475

"""Show formatted file size."""

476

if obj.size:

477

return f"{obj.size:,} bytes"

478

return "Unknown"

479

size_formatted.short_description = "Size"

480

481

# Custom filter for file types

482

class FileTypeFilter(admin.SimpleListFilter):

483

title = 'File Type'

484

parameter_name = 'file_type'

485

486

def lookups(self, request, model_admin):

487

return (

488

('image', 'Images'),

489

('document', 'Documents'),

490

('video', 'Videos'),

491

('audio', 'Audio'),

492

)

493

494

def queryset(self, request, queryset):

495

if self.value() == 'image':

496

return queryset.filter(mime_type__startswith='image/')

497

elif self.value() == 'document':

498

return queryset.filter(mime_type__in=[

499

'application/pdf', 'application/msword',

500

'application/vnd.openxmlformats-officedocument.wordprocessingml.document'

501

])

502

# Add more filter logic as needed

503

return queryset

504

505

list_filter = [FileTypeFilter, 'is_public', 'folder']

506

507

admin.site.register(File, RichFileAdmin)

508

```