django-filer gives a Django site a browsable file and image library
File and Image Management Application for django
At a glance
- What is it?
- django-filer is a Django application that stores uploaded files and images as database-tracked model instances instead of loose paths, and ships a file picker, thumbnails and a folder tree for editors. It is BSD-3-Clause licensed, requires Python 3.8 or newer and Django 3.2 or newer, and is endorsed by the django CMS Association.
- Who is it for?
- django-filer fits a Django project where editors upload media through an interface and want to browse, reuse and reference files by model instance instead of by a path in a template, and it fits django CMS projects specifically, since the association endorsement and the addon.json manifest show it is treated as a first class part of that ecosystem.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Files become model instances, not paths
django-filer is described as a file management application for django that makes handling of files and images a breeze, and the screenshots the README embeds give the idea of the surface. There are panels for a file picker, a detail view for a single image and a detail view for a single file, and the main view is a list of the library with search and navigation.
The important design decision is that a file is a row. Instead of an ImageField on your own model that points at a file on disk or in a bucket, django-filer models the file itself, so you can attach a file to a page, a plugin or a gallery item by reference, and the file object carries its metadata, its folder, its name and the derived thumbnails along with it.
That model is what makes the picker work. A picker needs a browsable, queryable collection, and a directory tree on disk is not queryable without a second index. django-filer provides the index as the database, and the tree you see in the interface is a folder structure maintained as data.
The project is endorsed by the django CMS Association, and the README says what that means: it is officially accepted by the association as being in line with its roadmap vision and development and plugin policy. The repository carries an addon.json manifest and an aldryn_config.py at the top level. Between those two files, the package's place in the django CMS ecosystem is unambiguous.
The dependency list explains where the image handling comes from
The runtime dependencies in pyproject.toml are four, and each one is load bearing.
dependencies = [
"django>=3.2",
"django-polymorphic<5.0",
"easy-thumbnails",
"py-svg-hush",
]django-polymorphic is the key one. It is a model inheritance library that lets a single database table hold instances of several different models, and it is what allows a folder to contain files, images, and other kinds of media as one queryable collection rather than as separate tables. The version constraint of less than 5.0 is a deliberate cap on a major version that has not been validated here.
easy-thumbnails is the thumbnail engine. django-filer does not implement resizing, it delegates to a well known Django library for it, which means the behaviour of derived images, the storage backends and the template tags are easy-thumbnails behaviour that django-filer exposes.
py-svg-hush is the least familiar of the four and it addresses a specific problem: SVG is an XML document, so it can carry script and external references, and an SVG served as an image can be an attack vector. A library whose name refers to sanitising SVG is doing that work, which tells you the project treats uploaded vector art as untrusted input.
The development status classifier is Production/Stable, and the maintainers are listed as the Django CMS Association and contributors, with Divio AG as the original author in the authors field.
A front end built with gulp, webpack and Karma
The package.json shows a second toolchain alongside the Python one, and it is the part of the project that surprises people who expect a Django admin extension to be server rendered templates.
"engines": {
"node": ">=24.0.0"
},
"scripts": {
"build": "gulp build",
"watch": "gulp watch",
"webpack": "webpack",
"lint": "gulp lint",
"test": "gulp tests:unit"
}Node 24 or newer is required for development, and the browser tests run under Karma with Jasmine, with a Chrome launcher and html2js and json fixture preprocessors. The unit test script is gulp tests:unit.
The build has two halves. Gulp handles the Sass compilation, the iconfont generation through gulp-iconfont and gulp-iconfont-css, the autoprefixing and the linting through gulp-eslint-new, while Webpack handles the module bundling with babel-loader and webpack-merge. The runtime dependencies are only two, dropzone for drag and drop uploads and mediator-js as a publish-subscribe mediator, and jquery is a dev dependency rather than a runtime one, which is a sign of a deliberate push away from depending on jQuery at runtime.
The repository top level mirrors that split. There is a filer/ directory for the Python package, a tests/ directory, a docs/ directory, and the configuration files for each tool, including tox.ini for the Python test matrix, .coveragerc for coverage, a pre-commit-config.yaml, an eslint config, webpack.config.js and gulpfile.js. There is also a .tx/ directory, which is the configuration for the translation platform, so the interface strings are translated by contributors rather than by the maintainers.
Version support is wide, and the file format is old
The classifier list is the most informative part of the packaging metadata, and it is more current than the requires-python floor.
The project requires Python 3.8 or newer and Django 3.2 or newer, and the classifiers enumerate Django 3.2, 4.2, 5.0, 5.1, 5.2, 6.0 and 6.1, and django CMS 3.11, 4.0, 4.1, 5.0 and 5.1. On the Python side the classifiers list 3.10, 3.11, 3.12, 3.13 and 3.14, which is a wider set than the 3.8 floor implies. The gap between the two is normal, since the floor is what the code permits and the classifiers are what is tested and supported in practice, but it means a project on Python 3.8 satisfies the metadata and gets no classifier support.
The Django CMS version range is the more interesting line. django CMS 3.11, 4.0, 4.1, 5.0 and 5.1 is a very wide span for one package, and it reflects that django-filer is a stable model layer that the CMS versions share rather than something that changes with each release. If you are on an older django CMS, this is the component most likely to keep working.
The release history shows a steady cadence with recent work. The tags are 3.4.4 on 2026-02-06, 3.5.0 on 2026-07-06 and 3.5.1 on 2026-08-26, and the last push to master was on 2026-10-18. The version in pyproject.toml is dynamic, read from the package at build time, which is why there is no version field in the metadata.
One more detail about the format. The README file itself is README.rst, and the readme field points at it, so the project uses reStructuredText for its source documentation, with a CHANGELOG.rst alongside it. The older format is a deliberate choice by the django CMS ecosystem rather than an oversight, and it means the readthedocs documentation and the repository readme are produced from the same markup conventions.
Where django-filer is the wrong choice
The first wrong case is a project that deliberately has no file rows. A common modern pattern is to store media in S3 or another object store, keep a URL in a text field, and have no database representation of the file at all. django-filer is the opposite of that design, and adopting it means reintroducing the row, the folder tree and the metadata. If your team deliberately removed database state for uploads, this package is a step backwards rather than a step forward.
The second wrong case is a project with no editor-facing interface. django-filer's value is concentrated in the picker and the library view, which exist for people who need to find an existing asset. If your application only accepts a file at upload time through a form field and never browses a library, the overhead of the model layer and the folder bookkeeping is not buying you anything, and easy-thumbnails on its own would be a smaller dependency.
The third wrong case is a Django version outside the supported range. The floor is Django 3.2, which is old enough that a project on it has other problems, and the classifiers stop at Django 6.1, so a project on a newer Django is outside what is tested even if the metadata permits it. django-polymorphic is also capped below version 5.0, so a project that needs the newer polymorphic release cannot use this package as it stands.
The fourth wrong case is treating the file store as a backup. The folder tree in the database describes the logical library, and the bytes live wherever easy-thumbnails and your storage settings put them. A deployment that migrates the database but not the underlying storage ends up with rows pointing at nothing, and the package does not ship a tool for reconciling the two.
How it differs from an ImageField on your own model
The comparison worth making is with the standard Django approach, because django-filer is a replacement for that pattern rather than an addition to it.
With an ImageField, you define a model with a file field, the upload lands at a path derived from the model and the filename, and the browser UI is a plain file input. To find an existing image you need to know its path, so you either build a search index yourself or you accept that images are only reachable from the page that uses them. Reusing the same asset in two places means either duplicating the upload or pointing two fields at one path, which the framework does not model.
With django-filer, the file is an object with an identity, and the page, the plugin and the gallery item each point at that object. The picker is then just a search over files, and reuse is a foreign key. The folder tree gives the browsable hierarchy that a file system gives you for free on a laptop, and the polymorphic model lets the tree hold more than one kind of item.
The difference in approach also shows in the thumbnail handling. With a plain ImageField, generating a thumbnail means configuring easy-thumbnails yourself or writing your own processing. django-filer delegates the same work to the same library and exposes the result, so a derived image is a filer object too rather than a path in a cache directory.
The cost of the approach is the extra indirection. Every reference to a file becomes a model lookup, and every file carries a row that has to be managed, deduplicated and pruned. For a site with a handful of images that is overhead without benefit. For a site with a shared asset library and multiple content types referencing the same material, it is the difference between a workable editing experience and a folder of loose uploads.
Editorial conclusion
django-filer fits a Django project where editors upload media through an interface and want to browse, reuse and reference files by model instance instead of by a path in a template, and it fits django CMS projects specifically, since the association endorsement and the addon.json manifest show it is treated as a first class part of that ecosystem. It does not fit a project that stores media on object storage and wants no database rows for files, since the model instance is the point, and it does not fit a Django version below 3.2. Before adopting it, read the readthedocs installation and configuration pages, because the README deliberately keeps no setup steps, and note that the package requires Python 3.8 or newer while the classifiers list Python 3.10 through 3.14, and that the newest release is 3.5.1 from 2026-08-26.
Frequently asked questions
How do I install django-filer?
The README does not contain installation steps and points to the separate documentation at django-filer.readthedocs.io for all the details on how to install, configure and use django-filer. The package is published on PyPI as django-filer and requires Python 3.8 or newer with Django 3.2 or newer.
What does django-filer depend on?
The runtime dependencies are django>=3.2, django-polymorphic<5.0, easy-thumbnails and py-svg-hush. django-polymorphic provides the multi-type model layer, easy-thumbnails handles image resizing, and py-svg-hush sanitises SVG uploads.
Which Django and django CMS versions does django-filer support?
The classifiers list Django 3.2, 4.2, 5.0, 5.1, 5.2, 6.0 and 6.1, and django CMS 3.11, 4.0, 4.1, 5.0 and 5.1. The Python classifiers list 3.10 through 3.14, even though the requires-python floor is 3.8.
What is the license of django-filer?
The pyproject.toml declares license as BSD-3-Clause and the classifiers include the BSD License under OSI Approved, with a LICENSE file at the root of the repository. The project listing itself marks the licence as a custom one that GitHub cannot classify, so the file in the repository is the authoritative text.
Does django-filer work with django CMS?
Yes, the project is endorsed by the django CMS Association as being in line with its roadmap and plugin policy, the classifiers list django CMS 3.11 through 5.1, and the repository carries an addon.json manifest and an aldryn_config.py hook for the Aldryn platform.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/django-cms-django-filer)