0
# Core Models
1
2
Django Filer's polymorphic model system provides comprehensive file and folder management with metadata support, permissions, and admin integration. The models form a hierarchical structure that can handle various file types through polymorphic inheritance.
3
4
## Capabilities
5
6
### File Model
7
8
The base polymorphic model for all file types in the filer system, providing common functionality for file handling, permissions, and metadata management.
9
10
```python { .api }
11
class File(PolymorphicModel):
12
"""
13
Base polymorphic file model with common file functionality.
14
15
Fields:
16
- folder: ForeignKey to Folder (nullable)
17
- file: MultiStorageFileField for file storage
18
- _file_size: BigIntegerField - cached file size in bytes
19
- name: CharField(max_length=255) - display name
20
- description: TextField (nullable) - file description
21
- original_filename: CharField(max_length=255) - original upload name
22
- owner: ForeignKey to User (nullable)
23
- has_all_mandatory_data: BooleanField - validation flag
24
- is_public: BooleanField - public/private flag
25
- mime_type: CharField(max_length=255)
26
- sha1: CharField(max_length=40) - file hash
27
- uploaded_at: DateTimeField (auto_now_add=True)
28
- modified_at: DateTimeField (auto_now=True)
29
"""
30
31
def save(self, *args, **kwargs):
32
"""Save the file, generating SHA1 hash if needed."""
33
34
def delete(self, *args, **kwargs):
35
"""Delete the file and clean up storage."""
36
37
def generate_sha1(self):
38
"""Generate SHA1 hash for the file content."""
39
40
def has_read_permission(self, request):
41
"""Check if user has read permission for this file."""
42
43
def has_edit_permission(self, request):
44
"""Check if user has edit permission for this file."""
45
46
def has_add_children_permission(self, request):
47
"""Check if user has permission to add children to this file's folder."""
48
49
def get_admin_change_url(self):
50
"""Get the admin change URL for this file."""
51
52
def get_admin_delete_url(self):
53
"""Get the admin delete URL for this file."""
54
55
@property
56
def url(self):
57
"""Get the public URL for this file."""
58
59
@property
60
def path(self):
61
"""Get the file system path for this file."""
62
63
@property
64
def size(self):
65
"""Get the file size in bytes."""
66
67
@property
68
def extension(self):
69
"""Get the file extension."""
70
71
@property
72
def label(self):
73
"""Get a human-readable label for the file."""
74
75
@property
76
def canonical_url(self):
77
"""Get the canonical URL for this file."""
78
79
@property
80
def logical_folder(self):
81
"""Get the logical folder containing this file."""
82
83
@property
84
def logical_path(self):
85
"""Get the logical path to this file."""
86
87
@property
88
def duplicates(self):
89
"""Get other files with the same SHA1 hash."""
90
```
91
92
### FileManager
93
94
Custom manager for the File model providing duplicate detection functionality.
95
96
```python { .api }
97
class FileManager(PolymorphicManager):
98
"""Custom manager for File model with duplicate detection."""
99
100
def find_all_duplicates(self):
101
"""
102
Find all duplicate files based on SHA1 hash.
103
104
Returns:
105
dict: Dictionary mapping SHA1 hashes to QuerySets of duplicate files
106
"""
107
108
def find_duplicates(self, file_obj):
109
"""
110
Find duplicates of a specific file.
111
112
Args:
113
file_obj (File): File to find duplicates of
114
115
Returns:
116
list: List of File objects that are duplicates
117
"""
118
```
119
120
### Folder Model
121
122
Model for hierarchical folder organization with permission system and file management capabilities.
123
124
```python { .api }
125
class Folder(models.Model):
126
"""
127
Hierarchical folder model for organizing files.
128
129
Fields:
130
- parent: ForeignKey to self (nullable) - parent folder
131
- name: CharField(max_length=255) - folder name
132
- owner: ForeignKey to User (nullable) - folder owner
133
- uploaded_at: DateTimeField (auto_now_add=True)
134
- created_at: DateTimeField (auto_now_add=True)
135
- modified_at: DateTimeField (auto_now=True)
136
"""
137
138
def save(self, *args, **kwargs):
139
"""Save the folder with validation."""
140
141
def delete(self, *args, **kwargs):
142
"""Delete the folder and handle children."""
143
144
def has_read_permission(self, request):
145
"""Check if user has read permission for this folder."""
146
147
def has_edit_permission(self, request):
148
"""Check if user has edit permission for this folder."""
149
150
def has_add_children_permission(self, request):
151
"""Check if user has permission to add children to this folder."""
152
153
def get_admin_change_url(self):
154
"""Get the admin change URL for this folder."""
155
156
def get_admin_directory_listing_url_path(self):
157
"""Get the admin directory listing URL for this folder."""
158
159
def contains_folder(self, folder_name):
160
"""Check if this folder contains a child folder with the given name."""
161
162
def get_descendants_ids(self):
163
"""Get IDs of all descendant folders."""
164
165
@property
166
def file_count(self):
167
"""Get the number of files in this folder."""
168
169
@property
170
def children_count(self):
171
"""Get the number of child folders."""
172
173
@property
174
def item_count(self):
175
"""Get the total number of items (files + folders)."""
176
177
@property
178
def files(self):
179
"""Get all files in this folder."""
180
181
@property
182
def logical_path(self):
183
"""Get the logical path to this folder."""
184
185
@property
186
def pretty_logical_path(self):
187
"""Get a human-readable logical path."""
188
```
189
190
### Image Models
191
192
Image-specific models extending the base File model with image metadata and processing capabilities.
193
194
```python { .api }
195
class BaseImage(File):
196
"""
197
Abstract base class for image models.
198
199
Fields:
200
- _width: FloatField (nullable) - image width
201
- _height: FloatField (nullable) - image height
202
- _transparent: BooleanField (nullable) - has transparency
203
- default_alt_text: CharField(max_length=255) - default alt text
204
- default_caption: CharField(max_length=255) - default caption
205
- subject_location: CharField(max_length=64) - subject location for cropping
206
"""
207
208
def matches_file_type(self):
209
"""Check if the file matches the image type."""
210
211
def file_data_changed(self):
212
"""Handle image data changes."""
213
214
def clean(self):
215
"""Validate the image model."""
216
217
def sidebar_image_ratio(self):
218
"""Calculate the sidebar image ratio."""
219
220
@property
221
def width(self):
222
"""Get the image width."""
223
224
@property
225
def height(self):
226
"""Get the image height."""
227
228
@property
229
def exif(self):
230
"""Get EXIF data from the image."""
231
232
@property
233
def icons(self):
234
"""Get icon representations of the image."""
235
236
@property
237
def thumbnails(self):
238
"""Get thumbnail representations of the image."""
239
240
@property
241
def easy_thumbnails_thumbnailer(self):
242
"""Get easy-thumbnails thumbnailer instance."""
243
244
class Image(BaseImage):
245
"""
246
Default concrete image model (swappable via FILER_IMAGE_MODEL).
247
248
Fields:
249
- date_taken: DateTimeField (nullable) - when photo was taken
250
- author: CharField(max_length=255) - image author
251
- must_always_publish_author_credit: BooleanField - author credit requirement
252
- must_always_publish_copyright: BooleanField - copyright requirement
253
"""
254
255
def save(self, *args, **kwargs):
256
"""Save image with EXIF date extraction."""
257
```
258
259
### Permission System
260
261
Models for implementing granular folder-level permissions with caching support.
262
263
```python { .api }
264
class FolderPermission(models.Model):
265
"""
266
Permission model for folder access control.
267
268
Fields:
269
- folder: ForeignKey to Folder (nullable) - target folder
270
- type: SmallIntegerField - permission scope (ALL, THIS, CHILDREN)
271
- user: ForeignKey to User (nullable) - target user
272
- group: ForeignKey to Group (nullable) - target group
273
- everybody: BooleanField - applies to everyone
274
- can_read: SmallIntegerField (nullable) - read permission (ALLOW/DENY)
275
- can_edit: SmallIntegerField (nullable) - edit permission (ALLOW/DENY)
276
- can_add_children: SmallIntegerField (nullable) - add children permission (ALLOW/DENY)
277
"""
278
279
# Permission constants
280
ALLOW = 1
281
DENY = 0
282
283
# Permission scope constants
284
ALL = 0 # Permission applies to this folder and all descendants
285
THIS = 1 # Permission applies only to this folder
286
CHILDREN = 2 # Permission applies only to child folders
287
288
objects = FolderPermissionManager()
289
290
@property
291
def pretty_logical_path(self):
292
"""Get human-readable path for the permission."""
293
294
@property
295
def who(self):
296
"""Get description of who the permission applies to."""
297
298
@property
299
def what(self):
300
"""Get description of what permissions are granted."""
301
302
class FolderPermissionManager(models.Manager):
303
"""Manager for folder permissions with caching and efficient permission lookups."""
304
305
def get_read_id_list(self, user):
306
"""
307
Get list of folder IDs user can read with caching.
308
309
Args:
310
user: User to check permissions for
311
312
Returns:
313
set or str: Set of folder IDs or 'All' if superuser
314
"""
315
316
def get_edit_id_list(self, user):
317
"""
318
Get list of folder IDs user can edit with caching.
319
320
Args:
321
user: User to check permissions for
322
323
Returns:
324
set or str: Set of folder IDs or 'All' if superuser
325
"""
326
327
def get_add_children_id_list(self, user):
328
"""
329
Get list of folder IDs user can add children to with caching.
330
331
Args:
332
user: User to check permissions for
333
334
Returns:
335
set or str: Set of folder IDs or 'All' if superuser
336
"""
337
```
338
339
### Additional Models
340
341
Supporting models for clipboard functionality, thumbnail options, and file management.
342
343
```python { .api }
344
class Clipboard(models.Model):
345
"""
346
User clipboard for file management operations.
347
348
Fields:
349
- user: ForeignKey to User - clipboard owner
350
- files: ManyToManyField to File through ClipboardItem
351
"""
352
353
def append_file(self, file):
354
"""Add a file to the clipboard."""
355
356
def empty(self):
357
"""Remove all files from the clipboard."""
358
359
class ClipboardItem(models.Model):
360
"""
361
Through model for Clipboard-File relationship.
362
363
Fields:
364
- file: ForeignKey to File
365
- clipboard: ForeignKey to Clipboard
366
"""
367
368
class ThumbnailOption(models.Model):
369
"""
370
Model for defining thumbnail generation options.
371
372
Fields:
373
- name: CharField(max_length=100) - option name
374
- width: IntegerField - thumbnail width
375
- height: IntegerField - thumbnail height
376
- crop: BooleanField - whether to crop
377
- upscale: BooleanField - whether to upscale
378
"""
379
380
@property
381
def as_dict(self):
382
"""Get thumbnail options as dictionary for easy_thumbnails."""
383
```
384
385
### Virtual Items
386
387
Virtual folder classes for special organizational and filtering needs in the admin interface.
388
389
```python { .api }
390
class DummyFolder:
391
"""
392
Base class for virtual folders that don't exist in the database.
393
394
Provides folder-like interface for special collections of files
395
like unsorted images or files with missing data.
396
"""
397
398
def __init__(self):
399
"""Initialize virtual folder with basic properties."""
400
401
@property
402
def name(self):
403
"""Get the display name of the virtual folder."""
404
405
@property
406
def logical_path(self):
407
"""Get the logical path for the virtual folder."""
408
409
class UnsortedImages(DummyFolder):
410
"""
411
Virtual folder for images without folder assignment.
412
413
Shows all image files that have folder=None, providing
414
an easy way to organize orphaned images.
415
"""
416
417
class ImagesWithMissingData(DummyFolder):
418
"""
419
Virtual folder for files with incomplete metadata.
420
421
Shows files that are missing required metadata like
422
alt text, descriptions, or have has_all_mandatory_data=False.
423
"""
424
425
class FolderRoot(DummyFolder):
426
"""
427
Virtual root folder representing the top level of the folder hierarchy.
428
429
Acts as the parent of all top-level folders (parent=None).
430
"""
431
```
432
433
## Usage Examples
434
435
### Creating and Managing Files
436
437
```python
438
from filer.models import File, Folder
439
from django.core.files.base import ContentFile
440
from django.contrib.auth.models import User
441
442
# Create a folder
443
user = User.objects.get(username='admin')
444
folder = Folder.objects.create(name="Documents", owner=user)
445
446
# Create a file
447
content = ContentFile(b"Hello, World!")
448
file_obj = File.objects.create(
449
file=content,
450
name="hello.txt",
451
folder=folder,
452
owner=user,
453
is_public=True
454
)
455
456
# Check permissions
457
if file_obj.has_read_permission(request):
458
print(f"File URL: {file_obj.url}")
459
print(f"File size: {file_obj.size} bytes")
460
461
# Find duplicates
462
duplicates = File.objects.find_duplicates(file_obj)
463
print(f"Found {len(duplicates)} duplicates")
464
```
465
466
### Working with Images
467
468
```python
469
from filer.models import Image, Folder
470
from django.core.files.base import ContentFile
471
472
# Create an image
473
with open('photo.jpg', 'rb') as f:
474
image_content = ContentFile(f.read())
475
476
image = Image.objects.create(
477
file=image_content,
478
name="My Photo",
479
folder=folder,
480
author="John Doe",
481
default_alt_text="A beautiful landscape"
482
)
483
484
# Access image properties
485
print(f"Image dimensions: {image.width}x{image.height}")
486
print(f"Has transparency: {image._transparent}")
487
488
# Get thumbnail
489
thumbnails = image.thumbnails
490
```
491
492
### Managing Permissions
493
494
```python
495
from filer.models import FolderPermission
496
from django.contrib.auth.models import User, Group
497
498
# Grant read permission to specific user
499
user = User.objects.get(username='editor')
500
permission = FolderPermission.objects.create(
501
folder=folder,
502
user=user,
503
type=FolderPermission.ALL,
504
can_read=FolderPermission.ALLOW
505
)
506
507
# Check folder permissions
508
if folder.has_edit_permission(request):
509
print("User can edit this folder")
510
```