django-admin-superfilter
Advanced, modern filtering for Django admin changelists, with saved filters and selectable columns.
Features
- Search-bar style filter UI injected into Django admin changelists
- Type-aware filtering for text, numeric, boolean, choice, date, datetime and relation fields
- Field path traversal such as
author__email - Saved filters per authenticated user
- Column selection and ordering persisted with saved filters
- AJAX-backed relation picker using Django admin Select2 assets
- Support for custom filter fields via
SuperFilterField - Single JSON query parameter for rules (
sf) and one for visible columns (sfc) - Works without templates overrides
Requirements
- Python 3.10+
- Django 4.0+
Installation
Install the package:
pip install django-admin-superfilter
Add the app to INSTALLED_APPS:
INSTALLED_APPS = [
# ...
"superfilter",
]
Run migrations:
python manage.py migrate
Quick start
from django.contrib import admin
from superfilter.admin import SuperFilterAdminMixin
from .models import Bird
@admin.register(Bird)
class BirdAdmin(SuperFilterAdminMixin, admin.ModelAdmin):
list_display = ("species", "location", "count")
search_fields = ("species",)
Important:
- Put
SuperFilterAdminMixinbeforeadmin.ModelAdminin the MRO. - By default, filterable fields come from
list_display. - Non-model entries in
list_displayare ignored. - Traversed model fields like
location__city__nameare supported.
What appears in the UI
The package adds a search-bar-like control above the changelist with:
- an add-filter button
- filter badges for current rules
- an Apply button
- a split menu with Save
- a Reset button
- a Columns toggle button
- a collapsible column chooser
- saved filter chips
Saved filters store both:
- the active filter rules
- the selected column list and order
Supported field kinds and operators
All fields
setnot_set
Text-like fields
Text-like fields include CharField, TextField, EmailField, SlugField, URLField, UUIDField.
Operators:
setnot_seteqneqcontainsnot_containsinnot_in
Numeric fields
Operators:
setnot_seteqneqgtltgtelte
Boolean fields
Operators:
setnot_settruefalse
Choice fields
Operators:
setnot_setinnot_in
Foreign key / relation fields
Operators:
setnot_setinnot_in
Date and datetime fields
Operators:
setnot_seteqbeforeafterbetween
Semantics
setmeans the field is considered populatednot_setmeans the field is empty- For text fields, empty means
NULLor empty string - For boolean fields,
set/not_setonly targetNULLvs non-NULL containsusesicontainsnot_containsnegatesicontainsbetweenon date/datetime expects exactly two values- Relation filters use selected related object primary keys
Configuration
SuperFilterAdminMixin exposes a few attributes:
superfilter_param_name = "sf"superfilter_columns_param_name = "sfc"superfilter_fields = Nonesuperfilter_page_size = 25superfilter_all_limit = 2000
Example:
class BirdAdmin(SuperFilterAdminMixin, admin.ModelAdmin):
list_display = ("species", "location", "count")
superfilter_page_size = 50
superfilter_all_limit = 5000
Restricting filterable fields
By default, filterable fields are taken from list_display.
To expose a different set of fields, use superfilter_fields:
class BirdAdmin(SuperFilterAdminMixin, admin.ModelAdmin):
list_display = ("species", "location", "count")
superfilter_fields = ("species", "count", "location__city")
This only affects filterable fields. Column selection still uses list_display.
Custom filter fields
You can plug in custom fields that do not map directly to a Django model field.
Create a subclass of SuperFilterField:
from django.db.models import Q
from superfilter.logic import SuperFilterField
class HasLargeCountField(SuperFilterField):
path = "has_large_count"
label = "Large count"
kind = "choice"
choices = [
{"value": "yes", "label": "Yes"},
{"value": "no", "label": "No"},
]
def apply_rule(self, queryset, rule):
values = set(rule.get("value") or [])
if "yes" in values and "no" not in values:
return queryset.filter(count__gte=100)
if "no" in values and "yes" not in values:
return queryset.filter(count__lt=100)
return queryset
Register it in superfilter_fields:
class BirdAdmin(SuperFilterAdminMixin, admin.ModelAdmin):
list_display = ("species", "location", "count")
superfilter_fields = ("species", HasLargeCountField)
Saved filters
Saved filters are stored in the SavedSuperFilter model and are scoped by:
- user
- app label
- model name
- saved filter name
Notes:
- saving requires an authenticated user
- saved filters are private to the user
URL format
Rules are sent in the sf query parameter as JSON:
[
{"field": "species", "op": "contains", "value": "owl"},
{"field": "location", "op": "in", "value": [1, 2]},
{"field": "count", "op": "gte", "value": 10}
]
Columns are sent in the sfc query parameter as JSON:
["location", "species", "count"]
Relation option loading
For relation filters, the package exposes an admin endpoint that:
- reuses the related admin's
get_search_results()when available - otherwise falls back to searching up to three text fields
- otherwise falls back to PK search for numeric terms
Static assets
The mixin injects:
admin/css/vendor/select2/select2.min.cssadmin/js/vendor/select2/select2.full.min.jssuperfilter/superfilter.csssuperfilter/superfilter.js
No custom template override is required.
Limitations
- Filtering ignores callable/computed
list_displayentries unless implemented asSuperFilterField - Column selection only works on entries present in
list_display - The package ships with admin-focused frontend assets and is not intended for non-admin pages
Example project
A runnable sample project is available in:
examples/sampleapp/
Run it with:
cd examples/sampleapp
python manage.py migrate
python manage.py runserver
Development
Run tests from the repository root:
python manage.py test superfilter
Or use the sample project:
cd examples/sampleapp
python manage.py test
License
MIT. See LICENCE.md.
Metadata
Release files for django-admin-superfilter 0.9.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_admin_superfilter-0.9.4.tar.gz | 31.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_admin_superfilter-0.9.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 67.1 kB
Release files / django_admin_superfilter-0.9.4.tar.gz
| Download URL | django_admin_superfilter-0.9.4.tar.gz |
|---|---|
| Size | 31.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
eaa08e6a668b7bae88441956608ed58665088d1b503bf7fc488802b1adb3184e
|
|
BLAKE2b-256 checksum How to use checksums |
ebada30d9a50f7108d6adf67184c779217319d08d3b43c8fbca33f0093a81833
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.1 CPython/3.10.14 Windows/10
|
Release files / django_admin_superfilter-0.9.4-py3-none-any.whl
| Download URL | django_admin_superfilter-0.9.4-py3-none-any.whl |
|---|---|
| Size | 35.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5a582f41508a09d1f8c000fef1410407237c1b47f7689cc137604ad000f95136
|
|
BLAKE2b-256 checksum How to use checksums |
bafb8c12131376a82ef54c53c4ab7f37946ce7a86057b3feea8d1fe5e84f24fa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.1 CPython/3.10.14 Windows/10
|