Remote pagination and filtering for Tabulator on top of Django REST Framework.
Why this exists
Tabulator, in remote mode (pagination: "remote", filterMode: "remote", sortMode: "remote"), sends pagination/filtering/sorting using its own query string convention, and expects the response back in its own shape — neither matches what DRF ships out of the box (PageNumberPagination responds with {count, next, previous, results}; its filter_backends don’t understand nested bracketed keys). This package translates both sides. jQuery DataTables already has a mature DRF adapter (djangorestframework-datatables); no equivalent exists for Tabulator.
Usage
from rest_framework.generics import ListAPIView
from rest_framework_tabulator import TabulatorFilterBackend, TabulatorPagination
class DocumentListView(ListAPIView):
queryset = Document.objects.all()
serializer_class = DocumentSerializer
pagination_class = TabulatorPagination
filter_backends = [TabulatorFilterBackend]
filterset_fields = ['number', 'status', 'issued_at']
ordering_fields = ['issued_at', 'number', 'total']
Tabulator’s contract (confirmed against the source code of tabulator-tables/tabulator itself, not third-party documentation):
Request: page/size (pagination), sort[i][field]/ sort[i][dir] (sorting), filter[i][field]/filter[i][type]/ filter[i][value] (filtering) — an array value (the in type) is sent as filter[i][value][0], filter[i][value][1], etc.
Expected response: {"data": [...], "last_page": N}.
filterset_fields/ordering_fields on the view are allowlists of fields (same attribute names django-filter/rest_framework.filters .OrderingFilter already use, so they look familiar) — any field not declared there is silently ignored, on both the filter and the sort side. Leaving either one undeclared denies filtering/sorting entirely rather than allowing every field by default.
A computed or renamed serializer field (a SerializerMethodField, a source= field, anything without a same-named model field) needs a dict instead of a plain list, mapping the client-facing name to the real ORM lookup path(s):
filterset_fields = {
'status': 'state', # renamed field
'customer': ['customer__name', 'customer__id'], # search both at once
}
ordering_fields = {
'customer': ['customer__name', 'customer__id'], # tie-break, in order
}
A list of paths is combined with OR when filtering (e.g. one customer column that matches on either a name or an id), and chained as tie-breakers, in that order, when sorting.
Supported filter types
Every filter type Tabulator ships is supported (confirmed against Filter/defaults/filters.js in the Tabulator source for the exact set of built-in types):
Tabulator type |
Django lookup |
|---|---|
= |
exact |
!= |
negated exact |
<, <=, >, >= |
lt, lte, gt, gte |
like |
icontains |
keywords |
icontains (see note below) |
starts |
istartswith |
ends |
iendswith |
regex |
regex |
in |
in (array value) |
smart |
ported from Tabulator’s own smart filter |
smarter |
ported from Tabulator’s own smarter filter |
keywords note: Tabulator’s client-side keywords filter also supports a custom word separator and an “all words must match” toggle (headerFilterFuncParams), but neither is sent to the server in remote mode — the ajax payload only ever carries {field, type, value}. It is approximated here as a plain substring match, same as like.
smart/smarter are a faithful port of Tabulator’s own filter functions, not a Django-specific addition: . matches any non-empty value, ! matches empty/null, a leading comparison operator does a numeric comparison, a leading = does an exact match, multiple whitespace-separated words become an AND of a substring match per word, AND/OR combine sub-expressions left to right (no operator precedence, same as the original), and anything else falls back to a substring match.
A value that doesn’t fit the field’s type (e.g. a non-numeric string against an integer field, or an invalid date) raises a DRF ValidationError — a clean 400 naming the offending field — instead of an unhandled 500. Django validates most field types eagerly, right when the filter is applied, so this is caught there rather than only when the queryset is evaluated.
License
MIT — see LICENSE.
Development
pip install -e '.[dev]'
pytest
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file djangorestframework_tabulator-0.1.1.tar.gz.
File metadata
- Download URL: djangorestframework_tabulator-0.1.1.tar.gz
- Upload date:
- Size: 13.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eba7ffe63d1b9b8e74d1a658917e31b2d7398877d58adfee25e3e108e6169428
|
|
| MD5 |
13258be868d134787dccc8c6dd2acbea
|
|
| BLAKE2b-256 |
8f2e3c480892d2dc846a485ffa18849d716844d4117109e0473ec6cb21a117ef
|
File details
Details for the file djangorestframework_tabulator-0.1.1-py3-none-any.whl.
File metadata
- Download URL: djangorestframework_tabulator-0.1.1-py3-none-any.whl
- Upload date:
- Size: 11.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28693165dff507c1ac0c52561aaa03180309ef63a3a00e6d71443fc4049a74d7
|
|
| MD5 |
6a9e32ef28b5131874c818f382c5133e
|
|
| BLAKE2b-256 |
20418810962cc1f544deb8106b2e6c9f59db97d644141dea88d03f303f12f8d8
|