How to Add Custom Filters to Wagtail Images Admin View

by Maxime Decooman
The Challenge
Wagtail's images admin interface is powerful, but sometimes you need additional filtering capabilities. A common requirement is filtering images by file format (JPEG, PNG, GIF, WebP, etc.) to help content editors quickly find the right type of image.
The traditional approach of overriding URLs and views can lead to namespace conflicts and Django warnings. This article shows you a clean, maintainable solution using Django's app configuration system.
The Elegant Solution
Instead of wrestling with URL overrides, we'll use Django's app ready()
method to monkey patch Wagtail's images IndexView class.
Step 1: Create a Custom FilterSet
First, create a custom filterset that extends Wagtail's built-in ImagesFilterSet
:
# myproject/core/filters.py
from django_filters import ChoiceFilter
from wagtail.images import get_image_model
from wagtail.images.views.images import ImagesFilterSet
ImageModel = get_image_model()
class CustomImageFilterSet(ImagesFilterSet):
file_format = ChoiceFilter(
choices=[
('jpeg', 'JPEG'),
('jpg', 'JPG'),
('png', 'PNG'),
('gif', 'GIF'),
('webp', 'WebP'),
],
method='filter_by_format',
label='File Format'
)
def filter_by_format(self, queryset, name, value):
if value:
return queryset.filter(file__iendswith=f'.{value}')
return queryset
class Meta:
model = ImageModel
fields = ['file_format']
Step 2: Apply the FilterSet Using App Configuration
Now, use your Django app's ready()
method to monkey patch the images view:
# myproject/core/apps.py
from django.apps import AppConfig
class CoreConfig(AppConfig):
"""Config for the core app."""
default = True
default_auto_field = "django.db.models.BigAutoField"
name = "myproject.core"
def ready(self):
from wagtail.images.views.images import IndexView as ImagesIndexView
from .filters import CustomImageFilterSet
ImagesIndexView.filterset_class = CustomImageFilterSet
That's It!
With just these two files, you now have a custom file format filter in your Wagtail images admin. The filter appears as a dropdown in the images list view, allowing editors to quickly filter by JPEG, PNG, GIF, or WebP files.
Extending the Solution
You can easily add more filters to your CustomImageFilterSet
:
class CustomImageFilterSet(ImagesFilterSet):
file_format = ChoiceFilter(
choices=[
('jpeg', 'JPEG'),
('jpg', 'JPG'),
('png', 'PNG'),
('gif', 'GIF'),
('webp', 'WebP'),
],
method='filter_by_format',
label='File Format'
)
file_size = ChoiceFilter(
choices=[
('small', 'Small (< 100KB)'),
('medium', 'Medium (100KB - 1MB)'),
('large', 'Large (> 1MB)'),
],
method='filter_by_size',
label='File Size'
)
def filter_by_format(self, queryset, name, value):
if value:
return queryset.filter(file__iendswith=f'.{value}')
return queryset
def filter_by_size(self, queryset, name, value):
if value == 'small':
return queryset.filter(file_size__lt=100000)
elif value == 'medium':
return queryset.filter(file_size__gte=100000, file_size__lt=1000000)
elif value == 'large':
return queryset.filter(file_size__gte=1000000)
return queryset
class Meta:
model = ImageModel
fields = ['file_format', 'file_size']
Alternative Approaches (Not Recommended)
I explored several other approaches:
- URL Override with Hooks - Lead to namespace conflicts
- Custom Admin URLs - Requires complex and brittle URL management
- ViewSet Replacement - Brittle solution with future updates and can have side effects
✅ A maintainable solution
By leveraging Django's app configuration system and monkey patching, we achieved a clean solution that:
- Adds custom filtering to Wagtail's images admin
- Leverages Django's app lifecycle
- Maintains full compatibility with existing functionality
- Avoids URL conflicts and namespace issues
- Uses minimal code
This pattern can be applied to customize other Wagtail admin views as well, making it a valuable technique for any Wagtail developer's toolkit.