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