A file management application for Django that makes handling of files and images a breeze.
—
Django Filer provides template tags for file handling and image processing, plus utility functions for file operations, validation, and thumbnail processing. These components facilitate frontend integration and programmatic file manipulation.
Template tags and filters for displaying and manipulating filer objects in Django templates.
# filer_tags - Core file template tags
from filer.templatetags.filer_tags import *
def filesize(bytes, format='auto1024'):
"""
Format file size in human-readable format.
Args:
bytes (int): File size in bytes
format (str): Format type ('auto1024', 'auto1000', etc.)
Returns:
str: Formatted file size (e.g., "1.5 MB", "2.3 KB")
Usage:
{{ file.size|filesize }}
{{ file.size|filesize:"auto1000" }}
"""
# filer_image_tags - Image manipulation template tags
from filer.templatetags.filer_image_tags import *
def extra_padding_x(image, padding):
"""
Add horizontal padding to image dimensions.
Args:
image: Image object
padding (int): Padding amount in pixels
Returns:
int: Image width plus padding
Usage:
{{ image.width|extra_padding_x:10 }}
"""
def extra_padding_x_keep_ratio(image, padding):
"""
Add horizontal padding to image while maintaining aspect ratio.
Args:
image: Image object
padding (int): Padding amount in pixels
Returns:
int: Adjusted image width maintaining aspect ratio
Usage:
{{ image.width|extra_padding_x_keep_ratio:10 }}
"""
def extra_padding_y(image, padding):
"""
Add vertical padding to image dimensions.
Args:
image: Image object
padding (int): Padding amount in pixels
Returns:
int: Image height plus padding
Usage:
{{ image.height|extra_padding_y:5 }}
"""
def extra_padding_y_keep_ratio(image, padding):
"""
Add vertical padding to image while maintaining aspect ratio.
Args:
image: Image object
padding (int): Padding amount in pixels
Returns:
int: Adjusted image height maintaining aspect ratio
Usage:
{{ image.height|extra_padding_y_keep_ratio:5 }}
"""
def divide_x_by(image, divisor):
"""
Divide image width by specified value.
Args:
image: Image object
divisor (int): Value to divide by
Returns:
int: Image width divided by divisor
Usage:
{{ image.width|divide_x_by:2 }}
"""
def divide_y_by(image, divisor):
"""
Divide image height by specified value.
Args:
image: Image object
divisor (int): Value to divide by
Returns:
int: Image height divided by divisor
Usage:
{{ image.height|divide_y_by:3 }}
"""
def divide_xy_by(image, divisor):
"""
Divide both image dimensions by specified value.
Args:
image: Image object
divisor (int): Value to divide by
Returns:
tuple: (width/divisor, height/divisor)
Usage:
{% with dimensions=image|divide_xy_by:2 %}
Width: {{ dimensions.0 }}, Height: {{ dimensions.1 }}
{% endwith %}
"""
def get_css_position(image):
"""
Get CSS background-position based on image subject location.
Args:
image: Image object with subject_location
Returns:
str: CSS background-position value (e.g., "50% 30%")
Usage:
<div style="background-position: {{ image|get_css_position }};">
"""
# filer_admin_tags - Admin-specific template tags
from filer.templatetags.filer_admin_tags import *
def filer_actions(cl):
"""
Render admin action field for bulk operations.
Args:
cl: ChangeList object from admin
Returns:
dict: Context for action template
Usage:
{% filer_actions cl %}
"""
def filer_folder_list_type_switcher(current_list_type):
"""
Render list view switcher (table/thumbnail).
Args:
current_list_type: Current view type ('tb' or 'th')
Returns:
dict: Context for switcher template
Usage:
{% filer_folder_list_type_switcher 'tb' %}
"""
def filer_admin_context_url_params(context):
"""
Get URL parameters from admin context.
Args:
context: Template context
Returns:
str: URL query parameters
Usage:
{% filer_admin_context_url_params %}
"""
def filer_has_permission(item, action, request):
"""
Check user permissions for admin actions.
Args:
item: File or Folder object
action: Permission action ('read', 'edit', 'add_children')
request: HTTP request with user
Returns:
bool: True if user has permission
Usage:
{% filer_has_permission item 'edit' request %}
"""
def file_icon(file, detail=False, size=None):
"""
Render file icon for admin interface.
Args:
file: File object
detail: Show detailed icon (bool)
size: Icon size override
Returns:
str: Icon HTML
Usage:
{% file_icon file detail=True size=48 %}
"""Utility functions for file handling, upload processing, and filename generation.
from filer.utils.files import *
def handle_upload(request):
"""
Process file upload from request.
Args:
request: Django HTTP request with file upload
Returns:
File: Created filer File object
Raises:
UploadException: If upload processing fails
"""
def get_valid_filename(filename):
"""
Generate a valid, safe filename from input string.
Args:
filename (str): Original filename
Returns:
str: Sanitized filename safe for filesystem
"""
def slugify(value):
"""
Convert string to filename-safe slug.
Args:
value (str): Input string
Returns:
str: Slugified string suitable for filenames
"""
class UploadException(Exception):
"""Exception raised during file upload processing."""
# Filename generation functions
from filer.utils.generate_filename import *
def randomized(instance, filename):
"""
Generate randomized filename for file uploads.
Args:
instance: Model instance
filename (str): Original filename
Returns:
str: Randomized filename preserving extension
"""
def by_date(instance, filename):
"""
Generate date-based filename for file uploads.
Args:
instance: Model instance
filename (str): Original filename
Returns:
str: Date-based filename with YYYY/MM/DD structure
"""
def prefixed_factory(upload_to, prefix):
"""
Create upload path generator with prefix.
Args:
upload_to: Base upload function
prefix (str): Prefix to add to paths
Returns:
function: Upload path generator function
"""
# Loading utilities
from filer.utils.loader import *
def load_object(import_path):
"""
Import object from dotted path string.
Args:
import_path (str): Dotted path to object (e.g., 'myapp.models.MyModel')
Returns:
object: Imported object
Raises:
ImportError: If import fails
"""
def load_model(model_string):
"""
Load Django model by string.
Args:
model_string (str): Model string (e.g., 'auth.User')
Returns:
Model: Django model class
"""
def storage_factory(klass, location=None, base_url=None):
"""
Create storage instance from class and parameters.
Args:
klass: Storage class or import path
location: Storage location path
base_url: Base URL for storage
Returns:
Storage: Configured storage instance
"""File validation utilities for security and content validation.
from filer.validation import *
def validate_upload(file_obj):
"""
Main file upload validation function.
Args:
file_obj: File object to validate
Raises:
FileValidationError: If file fails validation
ValidationError: If file violates Django validation rules
"""
def validate_svg(file_obj):
"""
Security validation for SVG files.
Args:
file_obj: SVG file object to validate
Raises:
FileValidationError: If SVG contains dangerous content
"""
def deny(message="File type not allowed"):
"""
Validation denial function.
Args:
message (str): Error message
Raises:
FileValidationError: Always raises with provided message
"""
def deny_html(file_obj):
"""
Validation function to deny HTML files.
Args:
file_obj: File object to check
Raises:
FileValidationError: If file is HTML content
"""
class FileValidationError(Exception):
"""Custom exception for file validation errors."""Folder permission caching utilities for performance optimization.
from filer.cache import *
def get_folder_permission_cache(user, permission_type):
"""
Retrieve cached folder permissions for user.
Args:
user: Django User object
permission_type (str): Type of permission ('can_read', 'can_edit', 'can_add_children')
Returns:
set or None: Set of folder IDs or None if not cached
"""
def update_folder_permission_cache(user, permission_type, folder_ids):
"""
Update folder permission cache for user.
Args:
user: Django User object
permission_type (str): Type of permission
folder_ids (set): Set of folder IDs user has permission for
"""
def clear_folder_permission_cache(user=None):
"""
Clear folder permission cache.
Args:
user (optional): Specific user to clear cache for, or None for all users
"""Image processing functions for thumbnail generation with easy-thumbnails integration.
from filer.thumbnail_processors import *
def scale_and_crop_with_subject_location(im, requested_size, opts):
"""
Scale and crop image considering subject location for smart cropping.
Args:
im: PIL Image object
requested_size (tuple): Target (width, height)
opts (dict): Processing options
Returns:
PIL.Image: Processed image
Usage in THUMBNAIL_PROCESSORS:
'filer.thumbnail_processors.scale_and_crop_with_subject_location'
"""
def whitespace(im, requested_size, opts):
"""
Add whitespace padding to image instead of cropping.
Args:
im: PIL Image object
requested_size (tuple): Target (width, height)
opts (dict): Processing options including background color
Returns:
PIL.Image: Image with whitespace padding
Usage in THUMBNAIL_PROCESSORS:
'filer.thumbnail_processors.whitespace'
"""Storage backend classes for handling public and private file storage.
from filer.storage import *
class PublicFileSystemStorage(FileSystemStorage):
"""
Storage class for public files accessible via direct URL.
Configured via FILER_PUBLICMEDIA_* settings.
"""
class PrivateFileSystemStorage(FileSystemStorage):
"""
Storage class for private files requiring permission checks.
Configured via FILER_PRIVATEMEDIA_* settings.
Files served through Django views with permission validation.
"""{# Load template tags #}
{% load filer_tags %}
{% load filer_image_tags %}
{# Display file information #}
{% if article.attachment %}
<div class="file-attachment">
<a href="{{ article.attachment.url }}">
{{ article.attachment.name }}
</a>
<span class="file-size">({{ article.attachment.size|filesize }})</span>
</div>
{% endif %}
{# Display image with responsive sizing #}
{% if article.featured_image %}
<div class="featured-image">
<img src="{{ article.featured_image.url }}"
alt="{{ article.featured_image.default_alt_text }}"
width="{{ article.featured_image.width|divide_x_by:2 }}"
height="{{ article.featured_image.height|divide_y_by:2 }}" />
{# Image with subject-aware background positioning #}
<div class="hero-image"
style="background-image: url('{{ article.featured_image.url }}');
background-position: {{ article.featured_image|get_css_position }};">
</div>
</div>
{% endif %}
{# File listing with metadata #}
{% for file in folder.files %}
<div class="file-item">
<h4>{{ file.name }}</h4>
<p>Size: {{ file.size|filesize }}</p>
<p>Type: {{ file.mime_type }}</p>
{% if file.description %}
<p>{{ file.description }}</p>
{% endif %}
{# Show thumbnail for images #}
{% if file.file_type == 'Image' %}
<img src="{{ file.icons.48 }}" alt="Thumbnail" />
<p>Dimensions: {{ file.width }}x{{ file.height }}</p>
{% endif %}
</div>
{% endfor %}from filer.utils.files import handle_upload, get_valid_filename
from filer.models import File, Folder
from django.core.files.base import ContentFile
def process_user_upload(request):
"""Process file upload with validation and organization."""
try:
# Handle upload from request
uploaded_file = handle_upload(request)
# Generate safe filename
safe_name = get_valid_filename(uploaded_file.name)
# Organize into user folder
user_folder, created = Folder.objects.get_or_create(
name=f"User_{request.user.id}_Files",
owner=request.user
)
# Create file object
file_obj = File.objects.create(
file=uploaded_file.file,
name=safe_name,
folder=user_folder,
owner=request.user,
is_public=False # Private by default
)
return file_obj
except UploadException as e:
# Handle upload errors
logger.error(f"Upload failed: {e}")
return None
def bulk_process_files(file_paths):
"""Process multiple files programmatically."""
processed_files = []
for file_path in file_paths:
with open(file_path, 'rb') as f:
content = ContentFile(f.read())
# Generate safe filename
filename = get_valid_filename(os.path.basename(file_path))
file_obj = File.objects.create(
file=content,
name=filename,
original_filename=os.path.basename(file_path)
)
processed_files.append(file_obj)
return processed_filesfrom filer.validation import FileValidationError
from django.core.exceptions import ValidationError
def custom_image_validator(file_obj):
"""Custom validator for image files."""
if not file_obj.mime_type.startswith('image/'):
return # Only validate images
# Check image dimensions
if hasattr(file_obj, 'width') and hasattr(file_obj, 'height'):
if file_obj.width < 100 or file_obj.height < 100:
raise FileValidationError("Image must be at least 100x100 pixels")
if file_obj.width > 4000 or file_obj.height > 4000:
raise FileValidationError("Image must not exceed 4000x4000 pixels")
# Check file size
if file_obj.size > 5 * 1024 * 1024: # 5MB
raise FileValidationError("Image file must not exceed 5MB")
def corporate_filename_validator(file_obj):
"""Ensure corporate naming standards."""
import re
# Check for valid corporate filename pattern
if not re.match(r'^[A-Z][A-Za-z0-9_-]+\.[a-z]+$', file_obj.name):
raise FileValidationError(
"Filename must start with capital letter and contain only "
"letters, numbers, hyphens, and underscores"
)
# Register custom validators in settings.py
FILE_VALIDATORS = [
'filer.validation.validate_upload',
'myapp.validators.custom_image_validator',
'myapp.validators.corporate_filename_validator',
]# Custom template tags for permission checking
from django import template
from filer.models import File, Folder
register = template.Library()
@register.filter
def user_can_access(file_obj, user):
"""Check if user can access file."""
return file_obj.has_read_permission(user)
@register.filter
def user_can_edit(file_obj, user):
"""Check if user can edit file."""
return file_obj.has_edit_permission(user)
@register.inclusion_tag('filer/file_list.html', takes_context=True)
def show_user_files(context, folder=None):
"""Show files user has access to."""
user = context['request'].user
if folder:
files = folder.files.all()
else:
files = File.objects.all()
# Filter by permissions
accessible_files = [
f for f in files
if f.has_read_permission(user)
]
return {
'files': accessible_files,
'user': user,
'can_upload': folder.has_add_children_permission(user) if folder else False
}from filer.cache import clear_folder_permission_cache
from django.core.management.base import BaseCommand
class Command(BaseCommand):
"""Management command to clear permission cache."""
def add_arguments(self, parser):
parser.add_argument('--user', type=str, help='Clear cache for specific user')
def handle(self, *args, **options):
if options['user']:
from django.contrib.auth.models import User
user = User.objects.get(username=options['user'])
clear_folder_permission_cache(user)
self.stdout.write(f"Cleared cache for user: {user.username}")
else:
clear_folder_permission_cache()
self.stdout.write("Cleared all permission caches")
# Usage: python manage.py clear_filer_cache --user=johnInstall with Tessl CLI
npx tessl i tessl/pypi-django-filer