django-admin-autocomplete-filter
Adds fast autocomplete search to Django admin list filters for foreign key and many-to-many fields.
Repository Health
Technical Analysis
django-admin-autocomplete-filter is a small Django app that brings Django admin’s select2-powered autocomplete_fields widget into list_filter, something Django doesn’t support out of the box. Instead of scrolling a long native dropdown to filter a changelist by a foreign key or many-to-many field, admins get a searchable autocomplete box that queries results asynchronously as they type.
The package exposes two ways to use it: a subclassable AutocompleteFilter base class for explicit filter definitions, and an AutocompleteFilterFactory shortcut that generates a filter class on the fly for a given field name, including dotted lookups across related models (e.g. fourth__third__second__first). It also supports plugging in a custom search endpoint via AutocompleteJsonView when the default admin search behavior isn’t sufficient, and works alongside Grappelli-themed admin sites.
What You Get
AutocompleteFilterbase class to declare a searchable list filter for any FK or M2M fieldAutocompleteFilterFactoryshortcut to generate filters inline without a dedicated class, including support for nested/dotted relation lookups- A pluggable
AutocompleteJsonViewfor overriding the search endpoint and result queryset used by the widget - Customizable widget label text via a callable, model field name, or model method (
label_by) - Bundled JS/CSS assets and an admin template that wire the select2 widget into the standard
list_filtersidebar - Compatibility handling across Django’s
autocomplete_fieldsAPI changes (pre- and post-Django 3.2)
Common Use Cases
- Filtering an admin changelist by a foreign key field (e.g. filtering albums by artist) without scrolling hundreds of dropdown options
- Filtering by a many-to-many relation where the native admin dropdown becomes unusable at scale
- Building an admin filter over a nested relation path (e.g. filtering by a field two or three joins away) using
AutocompleteFilterFactory - Customizing what text is shown for each option in the filter widget, independent of the model’s
__str__method - Wiring admin filters to a custom, permission- or queryset-scoped search endpoint instead of Django’s default autocomplete view
Under The Hood
Architecture
The package is a thin single-module Django admin extension - no internal layering beyond filters.py and views.py plus bundled static/template assets - that hooks directly into Django’s own AutocompleteSelect widget and SimpleListFilter machinery via subclassing (AutocompleteFilter) and a metaclass-based factory (AutocompleteFilterFactory / NewMetaFilter) that dynamically generates one-off filter classes per field, including dotted relation lookups resolved by walking model._meta.get_field(). Media (JS/CSS) is injected into the ModelAdmin at filter-init time via a small _add_media helper. Because its whole surface is a subclass of Django’s own admin internals, the DJANGO_VERSION branch already present in __init__ (working around the pre/post-3.2 get_field() vs remote_field API change) shows that upstream Django API drift is what most directly threatens this package.
Tech Stack
Pure Python with a single runtime dependency, Django>=2.0 (per setup.py/requirements.txt) - no other third-party packages. It ships static assets (a jQuery-based autocomplete_filter_qs.js plus a CSS fix) and an admin template as Django static files rather than anything requiring a JS build step. The test suite is a full standalone Django project (tests/tests/settings.py, urls.py, wsgi.py) driving a fixture-backed testapp. Packaging is classic setuptools (setup.py, MANIFEST.in) published to PyPI; no CI workflow file is present in the repo.
Code Quality
The Django TestCase-based suite in tests/testapp/tests.py is reasonably thorough for the package’s size: it exercises FK, M2M, and reverse-relation filtering, the custom autocomplete JSON endpoint, and the get_queryset_for_field field-resolution logic, parametrized with subTest across multiple models and two authentication scenarios. There is no CI workflow to confirm these run automatically, no type hints, and no linter/formatter configuration anywhere in the repo. Error handling mostly delegates to Django’s own exceptions (FieldDoesNotExist, AttributeError) rather than adding custom validation.
What Makes It Unique
Its real contribution is bridging Django’s autocomplete_fields widget (built for single-object FK/M2M selection on change forms) into list_filter, which Django has never supported natively - and doing so generically enough to cover dotted, cross-model lookups through one factory function rather than requiring a hand-written subclass per filterable field. That is a genuine, common admin pain point solved cleanly, though the underlying mechanism is a small, focused extension of stock Django widgets rather than a new architecture of its own.