Django Filtering
A library for filtering Django Models.
The original usecase for this project required the following:
- provides a means of allowing users to filter modeled data
- provides the ability to group filters by
AND,ORandNOToperators - serializes, validates, etc.
A user interface (UI) is available for this package in the
django-filtering-ui
package.
State of development
This package is very much a work-in-progress. All APIs are completely unstable.
Installation
Install via pip or the preferred package manager:
pip install django-filtering
Add to the Django project's INSTALLED_APPS:
INSTALLED_APPS = [
# ...
'django_filtering',
# ...
]
Usage
Say you have a Post model that you want users to be able to filter.
We'd start by creating a FilterSet.
import django_filtering as filtering
class PostFilterSet(filtering.FilterSet):
title = filtering.Filter(
filtering.InputLookup('icontains', label="contains"),
label="Title",
)
author = filtering.Filter(
filtering.InputLookup('fullname__iexact', label="fullname is"),
filtering.InputLookup('email__iexact', label="email is"),
label="Author",
)
content = filtering.Filter(
filtering.InputLookup('icontains', label="contains"),
label="Content",
)
class Meta:
model = Post
This can also be expressed using the declarative style:
class PostFilterSet(filtering.FilterSet):
class Meta:
model = Post
fields = {
'title': ['icontains'],
'author': ['fullname__iexact', 'email__iexact'],
'content': ['icontains'],
}
Note, this package does not come with an interface for user filtering.
The django-filtering-ui package does provide an interface.
The filters can be posted in a Form. For example, we'll say we have a form
that has a single q JSON field.
q = [
'and',
[
['title', {'lookup': 'icontains', 'value': 'foo'}],
['content', {'lookup': 'icontains', 'value': 'bar'}],
]
]
The basic structure is an array with an operator and array of further criteria, where that can be a filter array or another operator grouping.
An example of a user posting filters could look like the following url:
/posts/?q=["and",[["title",{"lookup":"icontains","value":"foo"}],["content",{"lookup":"icontains","value":"bar"}]]
In this case we have a q query string value with JSON content.
This query data structure is documented in more detail later in this document.
Let's say this url is a listing view for Post objects, something that looks like:
def posts_list(request):
query_data = json.loads(request.GET.get('q', '[]'))
filterset = PostFilterSet(query_data)
queryset = filterset.filter_queryset()
return HttpResponse('\n'.join([o.get_absolute_url() for o in queryset]))
In this example view we use the PostFilterSet with the query string value.
We get the fitlered results by calling the <FilterSet>.filter_queryset method.
About the query data structure
The JSON serialiable query data is a loosely lisp'ish data structure that looks something like:
query-data := [<operator>, [<filter|operator>,...]]
operator := 'and' | 'or' | 'not' | 'xor'
filter := [<field-name>, {"lookup": <lookup>, "value": <value>}]
field-name := string
lookup := string
value := any
Note, the value can be of any JSON serialiable type.
Testing
Note, I'm testing within a docker container, because I never run anything locally. For the moment the container is simply run with:
docker run --rm --name django-filtering --workdir /code -v $PWD:/code -d python:3.12 sleep infinity
Then I execute commands on the shell within it:
docker exec django-filtering pip install -e '.[tests]'
docker exec -it django-filtering bash
Within the container's shell you can now execute pytest.
License
GPL v3 (see LICENSE file)
Copyright
© 2025 The Shadowserver Foundation
Release files for django-filtering 0.8.0
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_filtering-0.8.0.tar.gz | 49.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_filtering-0.8.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 82.9 kB
Release files / django_filtering-0.8.0.tar.gz
| Download URL | django_filtering-0.8.0.tar.gz |
|---|---|
| Size | 49.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
568fc8437a1b766a8b83c1eba751d4d316f8ca800b4225e586f84648fb2489e9
|
|
BLAKE2b-256 checksum How to use checksums |
fe48ed8177d47971a27195ddff563719c6eeedf38eb45d7c6d74aacf126b07b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|
Release files / django_filtering-0.8.0-py3-none-any.whl
| Download URL | django_filtering-0.8.0-py3-none-any.whl |
|---|---|
| Size | 33.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
01d330062bdec653ce06e002e4a094aa37f793fc829f43f20d82447f5bcb8c1c
|
|
BLAKE2b-256 checksum How to use checksums |
5e1ccbd59f598f13fa4c9f2d9ba31f4ec82df5db5047c205e83b345158468b6e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|