A file management application for Django that makes handling of files and images a breeze.
—
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.
The base polymorphic model for all file types in the filer system, providing common functionality for file handling, permissions, and metadata management.
class File(PolymorphicModel):
"""
Base polymorphic file model with common file functionality.
Fields:
- folder: ForeignKey to Folder (nullable)
- file: MultiStorageFileField for file storage
- _file_size: BigIntegerField - cached file size in bytes
- name: CharField(max_length=255) - display name
- description: TextField (nullable) - file description
- original_filename: CharField(max_length=255) - original upload name
- owner: ForeignKey to User (nullable)
- has_all_mandatory_data: BooleanField - validation flag
- is_public: BooleanField - public/private flag
- mime_type: CharField(max_length=255)
- sha1: CharField(max_length=40) - file hash
- uploaded_at: DateTimeField (auto_now_add=True)
- modified_at: DateTimeField (auto_now=True)
"""
def save(self, *args, **kwargs):
"""Save the file, generating SHA1 hash if needed."""
def delete(self, *args, **kwargs):
"""Delete the file and clean up storage."""
def generate_sha1(self):
"""Generate SHA1 hash for the file content."""
def has_read_permission(self, request):
"""Check if user has read permission for this file."""
def has_edit_permission(self, request):
"""Check if user has edit permission for this file."""
def has_add_children_permission(self, request):
"""Check if user has permission to add children to this file's folder."""
def get_admin_change_url(self):
"""Get the admin change URL for this file."""
def get_admin_delete_url(self):
"""Get the admin delete URL for this file."""
@property
def url(self):
"""Get the public URL for this file."""
@property
def path(self):
"""Get the file system path for this file."""
@property
def size(self):
"""Get the file size in bytes."""
@property
def extension(self):
"""Get the file extension."""
@property
def label(self):
"""Get a human-readable label for the file."""
@property
def canonical_url(self):
"""Get the canonical URL for this file."""
@property
def logical_folder(self):
"""Get the logical folder containing this file."""
@property
def logical_path(self):
"""Get the logical path to this file."""
@property
def duplicates(self):
"""Get other files with the same SHA1 hash."""Custom manager for the File model providing duplicate detection functionality.
class FileManager(PolymorphicManager):
"""Custom manager for File model with duplicate detection."""
def find_all_duplicates(self):
"""
Find all duplicate files based on SHA1 hash.
Returns:
dict: Dictionary mapping SHA1 hashes to QuerySets of duplicate files
"""
def find_duplicates(self, file_obj):
"""
Find duplicates of a specific file.
Args:
file_obj (File): File to find duplicates of
Returns:
list: List of File objects that are duplicates
"""Model for hierarchical folder organization with permission system and file management capabilities.
class Folder(models.Model):
"""
Hierarchical folder model for organizing files.
Fields:
- parent: ForeignKey to self (nullable) - parent folder
- name: CharField(max_length=255) - folder name
- owner: ForeignKey to User (nullable) - folder owner
- uploaded_at: DateTimeField (auto_now_add=True)
- created_at: DateTimeField (auto_now_add=True)
- modified_at: DateTimeField (auto_now=True)
"""
def save(self, *args, **kwargs):
"""Save the folder with validation."""
def delete(self, *args, **kwargs):
"""Delete the folder and handle children."""
def has_read_permission(self, request):
"""Check if user has read permission for this folder."""
def has_edit_permission(self, request):
"""Check if user has edit permission for this folder."""
def has_add_children_permission(self, request):
"""Check if user has permission to add children to this folder."""
def get_admin_change_url(self):
"""Get the admin change URL for this folder."""
def get_admin_directory_listing_url_path(self):
"""Get the admin directory listing URL for this folder."""
def contains_folder(self, folder_name):
"""Check if this folder contains a child folder with the given name."""
def get_descendants_ids(self):
"""Get IDs of all descendant folders."""
@property
def file_count(self):
"""Get the number of files in this folder."""
@property
def children_count(self):
"""Get the number of child folders."""
@property
def item_count(self):
"""Get the total number of items (files + folders)."""
@property
def files(self):
"""Get all files in this folder."""
@property
def logical_path(self):
"""Get the logical path to this folder."""
@property
def pretty_logical_path(self):
"""Get a human-readable logical path."""Image-specific models extending the base File model with image metadata and processing capabilities.
class BaseImage(File):
"""
Abstract base class for image models.
Fields:
- _width: FloatField (nullable) - image width
- _height: FloatField (nullable) - image height
- _transparent: BooleanField (nullable) - has transparency
- default_alt_text: CharField(max_length=255) - default alt text
- default_caption: CharField(max_length=255) - default caption
- subject_location: CharField(max_length=64) - subject location for cropping
"""
def matches_file_type(self):
"""Check if the file matches the image type."""
def file_data_changed(self):
"""Handle image data changes."""
def clean(self):
"""Validate the image model."""
def sidebar_image_ratio(self):
"""Calculate the sidebar image ratio."""
@property
def width(self):
"""Get the image width."""
@property
def height(self):
"""Get the image height."""
@property
def exif(self):
"""Get EXIF data from the image."""
@property
def icons(self):
"""Get icon representations of the image."""
@property
def thumbnails(self):
"""Get thumbnail representations of the image."""
@property
def easy_thumbnails_thumbnailer(self):
"""Get easy-thumbnails thumbnailer instance."""
class Image(BaseImage):
"""
Default concrete image model (swappable via FILER_IMAGE_MODEL).
Fields:
- date_taken: DateTimeField (nullable) - when photo was taken
- author: CharField(max_length=255) - image author
- must_always_publish_author_credit: BooleanField - author credit requirement
- must_always_publish_copyright: BooleanField - copyright requirement
"""
def save(self, *args, **kwargs):
"""Save image with EXIF date extraction."""Models for implementing granular folder-level permissions with caching support.
class FolderPermission(models.Model):
"""
Permission model for folder access control.
Fields:
- folder: ForeignKey to Folder (nullable) - target folder
- type: SmallIntegerField - permission scope (ALL, THIS, CHILDREN)
- user: ForeignKey to User (nullable) - target user
- group: ForeignKey to Group (nullable) - target group
- everybody: BooleanField - applies to everyone
- can_read: SmallIntegerField (nullable) - read permission (ALLOW/DENY)
- can_edit: SmallIntegerField (nullable) - edit permission (ALLOW/DENY)
- can_add_children: SmallIntegerField (nullable) - add children permission (ALLOW/DENY)
"""
# Permission constants
ALLOW = 1
DENY = 0
# Permission scope constants
ALL = 0 # Permission applies to this folder and all descendants
THIS = 1 # Permission applies only to this folder
CHILDREN = 2 # Permission applies only to child folders
objects = FolderPermissionManager()
@property
def pretty_logical_path(self):
"""Get human-readable path for the permission."""
@property
def who(self):
"""Get description of who the permission applies to."""
@property
def what(self):
"""Get description of what permissions are granted."""
class FolderPermissionManager(models.Manager):
"""Manager for folder permissions with caching and efficient permission lookups."""
def get_read_id_list(self, user):
"""
Get list of folder IDs user can read with caching.
Args:
user: User to check permissions for
Returns:
set or str: Set of folder IDs or 'All' if superuser
"""
def get_edit_id_list(self, user):
"""
Get list of folder IDs user can edit with caching.
Args:
user: User to check permissions for
Returns:
set or str: Set of folder IDs or 'All' if superuser
"""
def get_add_children_id_list(self, user):
"""
Get list of folder IDs user can add children to with caching.
Args:
user: User to check permissions for
Returns:
set or str: Set of folder IDs or 'All' if superuser
"""Supporting models for clipboard functionality, thumbnail options, and file management.
class Clipboard(models.Model):
"""
User clipboard for file management operations.
Fields:
- user: ForeignKey to User - clipboard owner
- files: ManyToManyField to File through ClipboardItem
"""
def append_file(self, file):
"""Add a file to the clipboard."""
def empty(self):
"""Remove all files from the clipboard."""
class ClipboardItem(models.Model):
"""
Through model for Clipboard-File relationship.
Fields:
- file: ForeignKey to File
- clipboard: ForeignKey to Clipboard
"""
class ThumbnailOption(models.Model):
"""
Model for defining thumbnail generation options.
Fields:
- name: CharField(max_length=100) - option name
- width: IntegerField - thumbnail width
- height: IntegerField - thumbnail height
- crop: BooleanField - whether to crop
- upscale: BooleanField - whether to upscale
"""
@property
def as_dict(self):
"""Get thumbnail options as dictionary for easy_thumbnails."""Virtual folder classes for special organizational and filtering needs in the admin interface.
class DummyFolder:
"""
Base class for virtual folders that don't exist in the database.
Provides folder-like interface for special collections of files
like unsorted images or files with missing data.
"""
def __init__(self):
"""Initialize virtual folder with basic properties."""
@property
def name(self):
"""Get the display name of the virtual folder."""
@property
def logical_path(self):
"""Get the logical path for the virtual folder."""
class UnsortedImages(DummyFolder):
"""
Virtual folder for images without folder assignment.
Shows all image files that have folder=None, providing
an easy way to organize orphaned images.
"""
class ImagesWithMissingData(DummyFolder):
"""
Virtual folder for files with incomplete metadata.
Shows files that are missing required metadata like
alt text, descriptions, or have has_all_mandatory_data=False.
"""
class FolderRoot(DummyFolder):
"""
Virtual root folder representing the top level of the folder hierarchy.
Acts as the parent of all top-level folders (parent=None).
"""from filer.models import File, Folder
from django.core.files.base import ContentFile
from django.contrib.auth.models import User
# Create a folder
user = User.objects.get(username='admin')
folder = Folder.objects.create(name="Documents", owner=user)
# Create a file
content = ContentFile(b"Hello, World!")
file_obj = File.objects.create(
file=content,
name="hello.txt",
folder=folder,
owner=user,
is_public=True
)
# Check permissions
if file_obj.has_read_permission(request):
print(f"File URL: {file_obj.url}")
print(f"File size: {file_obj.size} bytes")
# Find duplicates
duplicates = File.objects.find_duplicates(file_obj)
print(f"Found {len(duplicates)} duplicates")from filer.models import Image, Folder
from django.core.files.base import ContentFile
# Create an image
with open('photo.jpg', 'rb') as f:
image_content = ContentFile(f.read())
image = Image.objects.create(
file=image_content,
name="My Photo",
folder=folder,
author="John Doe",
default_alt_text="A beautiful landscape"
)
# Access image properties
print(f"Image dimensions: {image.width}x{image.height}")
print(f"Has transparency: {image._transparent}")
# Get thumbnail
thumbnails = image.thumbnailsfrom filer.models import FolderPermission
from django.contrib.auth.models import User, Group
# Grant read permission to specific user
user = User.objects.get(username='editor')
permission = FolderPermission.objects.create(
folder=folder,
user=user,
type=FolderPermission.ALL,
can_read=FolderPermission.ALLOW
)
# Check folder permissions
if folder.has_edit_permission(request):
print("User can edit this folder")Install with Tessl CLI
npx tessl i tessl/pypi-django-filer