django-admin-rangefilter: date and numeric range filters for the Django admin
A Django app that lets you filter data by date range and numeric range in the admin UI
At a glance
- What is it?
- django-admin-rangefilter adds date, datetime and numeric range filters to the Django admin, so an operator can filter a column by a typed interval instead of a fixed choice list. It is a small MIT licensed app with an active release line, though its packaging metadata and its documented requirements disagree about supported Python versions.
- Who is it for?
- django-admin-rangefilter fits a Django project whose admin operators need to slice a date or numeric column by an arbitrary interval, and the builder API means you can adopt one filter per model without touching the queryset code yourself.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 12 days 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 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The admin filter that only offers exact choices
Django's admin lets you attach filters to a list view, and the built-in options are constrained. A date field gives you a fixed set of choices such as today and the past seven days, and a numeric field gives you exact-value lookups. Neither handles the question an operator actually asks when investigating a data problem, which is how many rows fall between two arbitrary values. django-admin-rangefilter is a Django app that adds a filter by date range and numeric range to the admin UI, and its whole purpose is to replace the fixed choice list with an interval the operator types. The audience is therefore Django developers building internal tools where someone in support or operations needs to narrow a table by a range, and the value is entirely in the admin interface rather than in any new query capability.
Filter builders slot into list_filter like any Django filter
The integration point is deliberately unremarkable, which is what makes the app easy to adopt. You import builder classes from rangefilter.filters and place instances in the list_filter tuple of a ModelAdmin, exactly where a built-in filter class would go. The module exposes four builders: DateRangeFilterBuilder, DateTimeRangeFilterBuilder, NumericRangeFilterBuilder and DateRangeQuickSelectListFilterBuilder. The first three are the range filters, and the fourth is described in the example as a range plus QuickSelect filter, which is how the traditional date choices and the range input can live side by side in one admin filter. Because the builders are objects rather than classes, each one can carry its own configuration, and the mechanism behind them is Django's own filter API rather than a patched queryset layer, so nothing about how the list view fetches rows changes.
Installing the app and wiring it into a ModelAdmin
The package is published on PyPI and the README gives the install command as a pip invocation:
``pip install django-admin-rangefilter``Next, the app has to be registered under the name rangefilter, which is not the same string as the distribution name:
INSTALLED_APPS = (
...
'rangefilter',
...
)The documented requirements are Python 3.6+ and Django 1.11+. Once the app is registered, a filter is added by importing the builders and listing them in list_filter:
from datetime import datetime
from django.contrib import admin
from rangefilter.filters import (
DateRangeFilterBuilder,
DateTimeRangeFilterBuilder,
NumericRangeFilterBuilder,
DateRangeQuickSelectListFilterBuilder,
)
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_filter = (
("created_at", DateRangeFilterBuilder()),
(
"updated_at",
DateTimeRangeFilterBuilder(
title="Custom title",
default_start=datetime(2020, 1, 1),
default_end=datetime(2030, 1, 1),
),
),
("num_value", NumericRangeFilterBuilder()),
("created_at", DateRangeQuickSelectListFilterBuilder()), # Range + QuickSelect Filter
)After that, the Post admin in the example shows a range filter for created_at, a configurable datetime range filter for updated_at, a numeric range filter for num_value, and a combined range plus quick select filter. The datetime builder accepts a title and default_start and default_end values, which is how you ship a filter that opens with a sensible window already filled in rather than empty boxes.
The packaging metadata and the README disagree about Python support
Here is a concrete inconsistency worth checking before you pin a version. The README states the requirements as Python 3.6+ and Django 1.11+. The setup.py in the same repository declares python_requires as >=2.7 with 3.0.*, 3.1.*, 3.2.*, 3.3.* and 3.4.* excluded, which admits Python 2.7 and Python 3.5 as well. The same file lists install_requires as an empty list, and it also reads the version out of the package __init__.py with a regular expression rather than declaring it directly. The discrepancy is not harmful on its own, since a permissive range rarely blocks an install, but it does mean the metadata is not a reliable statement of what the code has been exercised against. The tool configuration tells a similar story from a different angle: the black configuration targets py36 through py312, while ruff and pylint both point at py312, so the formatting and linting baseline is newer Python than the README's stated floor.
The build tooling is broader than the app itself
The repository is small, but its dev tooling is not. pyproject.toml configures black with a line length of 100 and the isort profile set to black with use_parentheses enabled, pylint with py-version 3.12 and a disable list that turns off convention and refactor messages plus typecheck, bare-except and broad-except, and ruff with its own exclude list and a space indent style. The Makefile wires these together as named targets, including a lint target that chains the black, isort, pylint and yamllint checks, and a fmt target that runs isort and then black. Tests run through django-admin test --settings=tests.settings with PYTHONWARNINGS=all and PYTHONPATH pointed at the tests directory, and coverage runs the same test command under the coverage tool with source set to the project root. Publishing is a twine upload of the sdist and wheel, with a separate pre-release target that uploads to test.pypi.org, so a release candidate is exercised against the real index before it reaches the public one.
Content-Security-Policy is handled, but only for django-csp
Admin pages are full of inline styles and scripts, so a project running under a strict Content-Security-Policy needs the admin to emit nonces. The README has a short section on this: for Django 1.8+, if django-csp is installed, nonces will be added to style and script tags. That is a narrow integration, and it is worth being precise about what it means. The app checks for the presence of django-csp and then adds nonces to the tags it renders, so the mechanism works through that package's conventions rather than through a configuration option of its own. If your deployment sets a CSP header through some other mechanism, the README does not document a configuration key for pointing at it, and there is no documented way to supply your own nonce. The requirement lines also state Django 1.11+ as the floor, which is a different boundary from the Django 1.8+ mentioned in the CSP section.
An active release line with no major version to speak of
The release history shows a project that keeps shipping without having a stable API to preserve. The tagged releases are v0.15.0 on 2026-08-28, v0.14.0 on 2026-08-01 and v0.13.5 on 2025-12-13, and the last push to the repository was on 2026-10-11. The version stays below 1.0 while the tags climb in minor increments, which for a Django app means the packaging and the admin integration can change between minor versions without the usual deprecation promise of a 1.x release. The project is MIT licensed, and the setup.py declares the same licence, so there is no licensing obstacle to putting it in a commercial Django application. There is also a CHANGELOG.md and a CONTRIBUTING.md at the root, which is where you would look to understand what a version bump changed before upgrading a pinned dependency.
Editorial conclusion
django-admin-rangefilter fits a Django project whose admin operators need to slice a date or numeric column by an arbitrary interval, and the builder API means you can adopt one filter per model without touching the queryset code yourself. It is the wrong tool when the set of values is small and fixed, since a plain list filter already covers that case, and it is the wrong tool for a project whose admin must run under a Content-Security-Policy setup that django-csp does not cover. Verify first which Python versions the project actually supports, because the README states Python 3.6+ while setup.py declares python_requires of >=2.7 with 3.0 through 3.4 excluded, then confirm the app name to register is rangefilter and not django-admin-rangefilter, which is the package name on PyPI.
Frequently asked questions
How do I install django-admin-rangefilter?
The README gives pip install django-admin-rangefilter as the example, and then requires you to add rangefilter to INSTALLED_APPS. The documented requirements are Python 3.6+ and Django 1.11+.
How do I add a date range filter to a Django admin model?
Import DateRangeFilterBuilder from rangefilter.filters and add a tuple of the field name and the builder instance to the list_filter attribute of your ModelAdmin. The README example does this for a created_at field on a Post model.
Can I set default start and end dates on the range filter?
Yes. DateTimeRangeFilterBuilder accepts a title, a default_start and a default_end, and the README example passes datetime(2020, 1, 1) and datetime(2030, 1, 1) for those two values.
Does django-admin-rangefilter work with a Content-Security-Policy?
The README states that for Django 1.8+, if django-csp is installed, nonces will be added to style and script tags. It documents no other configuration option for supplying a nonce.
What is the difference between the package name and the app name?
The PyPI distribution is django-admin-rangefilter, while the app you register in INSTALLED_APPS is rangefilter, and the builders are imported from rangefilter.filters.
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/silentsokolov-django-admin-rangefilter)Was this useful?