djangorestframework-tabulator 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,82 @@
1
+ name: CI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches:
7
+ - main
8
+ pull_request:
9
+ branches:
10
+ - main
11
+
12
+ jobs:
13
+ tests:
14
+ name: Tests
15
+ timeout-minutes: 10
16
+ runs-on: ${{ matrix.os }}
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ os: [ubuntu-latest]
21
+ python-version: ['3.10', '3.12', '3.14']
22
+ django-version: ['4.2', '5.1', '6.1']
23
+ exclude:
24
+ # Django 6.x dropped support for Python < 3.12.
25
+ - python-version: '3.10'
26
+ django-version: '6.1'
27
+
28
+ steps:
29
+ - name: Check out repository
30
+ uses: actions/checkout@v4
31
+
32
+ - name: Set up Python ${{ matrix.python-version }}
33
+ uses: actions/setup-python@v5
34
+ with:
35
+ python-version: ${{ matrix.python-version }}
36
+
37
+ - name: Display Python version
38
+ run: python --version
39
+
40
+ - name: Install dependencies
41
+ # Django and the package's own dependencies (which include an
42
+ # unpinned djangorestframework) are resolved together, in one
43
+ # call — installing them separately lets pip pick the latest
44
+ # djangorestframework first regardless of the Django version
45
+ # this job is testing, which can be incompatible with it
46
+ # (confirmed: djangorestframework 3.18 requires django>=5.2, so
47
+ # forcing an older Django on top afterwards leaves a broken
48
+ # environment instead of the older djangorestframework pip
49
+ # would have picked resolving both together).
50
+ run: |
51
+ python -m pip install --upgrade pip
52
+ pip install -e '.[dev]' "django==${{ matrix.django-version }}.*"
53
+
54
+ - name: Run Ruff (lint)
55
+ run: ruff check .
56
+
57
+ - name: Run Ruff (format)
58
+ run: ruff format --check .
59
+
60
+ - name: Run mypy
61
+ run: mypy
62
+
63
+ - name: Run pytest
64
+ run: |
65
+ mkdir -p var
66
+ pytest -v \
67
+ --junitxml=var/tests-results.xml \
68
+ --cov=rest_framework_tabulator \
69
+ --cov-report=xml:var/tests-coverage.xml
70
+
71
+ - name: Upload pytest result report
72
+ if: failure()
73
+ uses: actions/upload-artifact@v4
74
+ with:
75
+ name: tests-results-python_${{ matrix.python-version }}-django_${{ matrix.django-version }}.xml
76
+ path: var/tests-results.xml
77
+
78
+ - name: Upload Coverage Report
79
+ uses: actions/upload-artifact@v4
80
+ with:
81
+ name: tests-coverage-python_${{ matrix.python-version }}-django_${{ matrix.django-version }}.xml
82
+ path: var/tests-coverage.xml
@@ -0,0 +1,16 @@
1
+ # Python.
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .venv/
6
+ venv/
7
+ .pytest_cache/
8
+ .ruff_cache/
9
+ .mypy_cache/
10
+ dist/
11
+ build/
12
+ .coverage
13
+ var/
14
+
15
+ # Operating-system specific files.
16
+ .DS_Store
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (C) 2026 Esteban De La Fuente Rubio / Derafu <https://www.derafu.dev>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,40 @@
1
+ .PHONY: install-dev lint format format-check typecheck test check build upload clean
2
+
3
+ VENV = .venv
4
+ VENV_READY = $(VENV)/.installed
5
+
6
+ $(VENV_READY): pyproject.toml
7
+ python3 -m venv $(VENV)
8
+ $(VENV)/bin/pip install --upgrade pip
9
+ $(VENV)/bin/pip install -e '.[dev]'
10
+ touch $(VENV_READY)
11
+
12
+ install-dev: $(VENV_READY)
13
+
14
+ lint: $(VENV_READY)
15
+ $(VENV)/bin/ruff check .
16
+
17
+ format: $(VENV_READY)
18
+ $(VENV)/bin/ruff format .
19
+
20
+ format-check: $(VENV_READY)
21
+ $(VENV)/bin/ruff format --check .
22
+
23
+ typecheck: $(VENV_READY)
24
+ $(VENV)/bin/mypy
25
+
26
+ test: $(VENV_READY)
27
+ $(VENV)/bin/pytest -v
28
+
29
+ check: lint format-check typecheck test
30
+
31
+ build: $(VENV_READY)
32
+ $(VENV)/bin/python -m build
33
+
34
+ upload: build
35
+ $(VENV)/bin/twine check dist/*
36
+ $(VENV)/bin/twine upload dist/*
37
+
38
+ clean:
39
+ rm -rf dist build *.egg-info .pytest_cache .ruff_cache .mypy_cache
40
+ find . -type d -name __pycache__ -exec rm -rf {} +
@@ -0,0 +1,186 @@
1
+ Metadata-Version: 2.5
2
+ Name: djangorestframework-tabulator
3
+ Version: 0.1.0
4
+ Summary: Remote pagination and filtering for Tabulator (tabulator.info) on Django REST Framework.
5
+ Author: Esteban De La Fuente Rubio / Derafu
6
+ License: MIT License
7
+
8
+ Copyright (C) 2026 Esteban De La Fuente Rubio / Derafu <https://www.derafu.dev>
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ License-File: LICENSE
28
+ Keywords: django,djangorestframework,filtering,pagination,tabulator
29
+ Classifier: Framework :: Django
30
+ Classifier: Framework :: Django :: 4
31
+ Classifier: Framework :: Django :: 5
32
+ Classifier: Intended Audience :: Developers
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Programming Language :: Python :: 3
35
+ Requires-Python: >=3.10
36
+ Requires-Dist: django>=4.2
37
+ Requires-Dist: djangorestframework>=3.15
38
+ Provides-Extra: dev
39
+ Requires-Dist: build; extra == 'dev'
40
+ Requires-Dist: django-stubs; extra == 'dev'
41
+ Requires-Dist: djangorestframework-stubs; extra == 'dev'
42
+ Requires-Dist: mypy; extra == 'dev'
43
+ Requires-Dist: pytest; extra == 'dev'
44
+ Requires-Dist: pytest-cov; extra == 'dev'
45
+ Requires-Dist: pytest-django; extra == 'dev'
46
+ Requires-Dist: ruff; extra == 'dev'
47
+ Requires-Dist: twine; extra == 'dev'
48
+ Description-Content-Type: text/x-rst
49
+
50
+ djangorestframework-tabulator
51
+ ==============================
52
+
53
+ |build-status-image| |pypi-version| |py-versions|
54
+
55
+ Remote pagination and filtering for `Tabulator <https://tabulator.info>`_
56
+ on top of `Django REST Framework <https://www.django-rest-framework.org>`_.
57
+
58
+ Why this exists
59
+ ----------------
60
+
61
+ Tabulator, in remote mode (``pagination: "remote"``, ``filterMode:
62
+ "remote"``, ``sortMode: "remote"``), sends pagination/filtering/sorting
63
+ using its own query string convention, and expects the response back in
64
+ its own shape — neither matches what DRF ships out of the box
65
+ (``PageNumberPagination`` responds with ``{count, next, previous,
66
+ results}``; its ``filter_backends`` don't understand nested bracketed
67
+ keys). This package translates both sides. `jQuery DataTables
68
+ <https://datatables.net>`_ already has a mature DRF adapter
69
+ (`djangorestframework-datatables
70
+ <https://pypi.org/project/djangorestframework-datatables/>`_); no
71
+ equivalent exists for Tabulator.
72
+
73
+ Usage
74
+ -----
75
+
76
+ .. code-block:: python
77
+
78
+ from rest_framework.generics import ListAPIView
79
+ from rest_framework_tabulator import TabulatorFilterBackend, TabulatorPagination
80
+
81
+ class DocumentListView(ListAPIView):
82
+ queryset = Document.objects.all()
83
+ serializer_class = DocumentSerializer
84
+ pagination_class = TabulatorPagination
85
+ filter_backends = [TabulatorFilterBackend]
86
+ filterset_fields = ['number', 'status', 'issued_at']
87
+ ordering_fields = ['issued_at', 'number', 'total']
88
+
89
+ Tabulator's contract (confirmed against the source code of
90
+ ``tabulator-tables/tabulator`` itself, not third-party documentation):
91
+
92
+ - Request: ``page``/``size`` (pagination), ``sort[i][field]``/
93
+ ``sort[i][dir]`` (sorting), ``filter[i][field]``/``filter[i][type]``/
94
+ ``filter[i][value]`` (filtering) — an array value (the ``in`` type) is
95
+ sent as ``filter[i][value][0]``, ``filter[i][value][1]``, etc.
96
+ - Expected response: ``{"data": [...], "last_page": N}``.
97
+
98
+ ``filterset_fields``/``ordering_fields`` on the view are allowlists of
99
+ fields (same attribute names ``django-filter``/``rest_framework.filters
100
+ .OrderingFilter`` already use, so they look familiar) — any field not
101
+ declared there is silently ignored, on both the filter and the sort
102
+ side. Leaving either one undeclared denies filtering/sorting entirely
103
+ rather than allowing every field by default.
104
+
105
+ Supported filter types
106
+ -----------------------
107
+
108
+ Every filter type Tabulator ships is supported (confirmed against
109
+ ``Filter/defaults/filters.js`` in the Tabulator source for the exact
110
+ set of built-in types):
111
+
112
+ .. list-table::
113
+ :header-rows: 1
114
+
115
+ * - Tabulator ``type``
116
+ - Django lookup
117
+ * - ``=``
118
+ - exact
119
+ * - ``!=``
120
+ - negated exact
121
+ * - ``<``, ``<=``, ``>``, ``>=``
122
+ - ``lt``, ``lte``, ``gt``, ``gte``
123
+ * - ``like``
124
+ - ``icontains``
125
+ * - ``keywords``
126
+ - ``icontains`` (see note below)
127
+ * - ``starts``
128
+ - ``istartswith``
129
+ * - ``ends``
130
+ - ``iendswith``
131
+ * - ``regex``
132
+ - ``regex``
133
+ * - ``in``
134
+ - ``in`` (array value)
135
+ * - ``smart``
136
+ - ported from Tabulator's own ``smart`` filter
137
+ * - ``smarter``
138
+ - ported from Tabulator's own ``smarter`` filter
139
+
140
+ ``keywords`` note: Tabulator's client-side ``keywords`` filter also
141
+ supports a custom word separator and an "all words must match" toggle
142
+ (``headerFilterFuncParams``), but neither is sent to the server in
143
+ remote mode — the ajax payload only ever carries ``{field, type,
144
+ value}``. It is approximated here as a plain substring match, same as
145
+ ``like``.
146
+
147
+ ``smart``/``smarter`` are a faithful port of Tabulator's own filter
148
+ functions, not a Django-specific addition: ``.`` matches any non-empty
149
+ value, ``!`` matches empty/null, a leading comparison operator does a
150
+ numeric comparison, a leading ``=`` does an exact match, multiple
151
+ whitespace-separated words become an ``AND`` of a substring match per
152
+ word, ``AND``/``OR`` combine sub-expressions left to right (no operator
153
+ precedence, same as the original), and anything else falls back to a
154
+ substring match.
155
+
156
+ A value that doesn't fit the field's type (e.g. a non-numeric string
157
+ against an integer field, or an invalid date) raises a DRF
158
+ ``ValidationError`` — a clean ``400`` naming the offending field —
159
+ instead of an unhandled ``500``. Django validates most field types
160
+ eagerly, right when the filter is applied, so this is caught there
161
+ rather than only when the queryset is evaluated.
162
+
163
+ License
164
+ -------
165
+
166
+ MIT — see ``LICENSE``.
167
+
168
+ Development
169
+ -----------
170
+
171
+ .. code-block:: bash
172
+
173
+ pip install -e '.[dev]'
174
+ pytest
175
+
176
+ .. |build-status-image| image:: https://github.com/derafu/djangorestframework-tabulator/actions/workflows/ci.yml/badge.svg
177
+ :target: https://github.com/derafu/djangorestframework-tabulator/actions/workflows/ci.yml
178
+ :alt: CI
179
+
180
+ .. |pypi-version| image:: https://img.shields.io/pypi/v/djangorestframework-tabulator.svg
181
+ :target: https://pypi.org/project/djangorestframework-tabulator/
182
+ :alt: Pypi version
183
+
184
+ .. |py-versions| image:: https://img.shields.io/pypi/pyversions/djangorestframework-tabulator.svg
185
+ :target: https://pypi.org/project/djangorestframework-tabulator/
186
+ :alt: Python versions
@@ -0,0 +1,137 @@
1
+ djangorestframework-tabulator
2
+ ==============================
3
+
4
+ |build-status-image| |pypi-version| |py-versions|
5
+
6
+ Remote pagination and filtering for `Tabulator <https://tabulator.info>`_
7
+ on top of `Django REST Framework <https://www.django-rest-framework.org>`_.
8
+
9
+ Why this exists
10
+ ----------------
11
+
12
+ Tabulator, in remote mode (``pagination: "remote"``, ``filterMode:
13
+ "remote"``, ``sortMode: "remote"``), sends pagination/filtering/sorting
14
+ using its own query string convention, and expects the response back in
15
+ its own shape — neither matches what DRF ships out of the box
16
+ (``PageNumberPagination`` responds with ``{count, next, previous,
17
+ results}``; its ``filter_backends`` don't understand nested bracketed
18
+ keys). This package translates both sides. `jQuery DataTables
19
+ <https://datatables.net>`_ already has a mature DRF adapter
20
+ (`djangorestframework-datatables
21
+ <https://pypi.org/project/djangorestframework-datatables/>`_); no
22
+ equivalent exists for Tabulator.
23
+
24
+ Usage
25
+ -----
26
+
27
+ .. code-block:: python
28
+
29
+ from rest_framework.generics import ListAPIView
30
+ from rest_framework_tabulator import TabulatorFilterBackend, TabulatorPagination
31
+
32
+ class DocumentListView(ListAPIView):
33
+ queryset = Document.objects.all()
34
+ serializer_class = DocumentSerializer
35
+ pagination_class = TabulatorPagination
36
+ filter_backends = [TabulatorFilterBackend]
37
+ filterset_fields = ['number', 'status', 'issued_at']
38
+ ordering_fields = ['issued_at', 'number', 'total']
39
+
40
+ Tabulator's contract (confirmed against the source code of
41
+ ``tabulator-tables/tabulator`` itself, not third-party documentation):
42
+
43
+ - Request: ``page``/``size`` (pagination), ``sort[i][field]``/
44
+ ``sort[i][dir]`` (sorting), ``filter[i][field]``/``filter[i][type]``/
45
+ ``filter[i][value]`` (filtering) — an array value (the ``in`` type) is
46
+ sent as ``filter[i][value][0]``, ``filter[i][value][1]``, etc.
47
+ - Expected response: ``{"data": [...], "last_page": N}``.
48
+
49
+ ``filterset_fields``/``ordering_fields`` on the view are allowlists of
50
+ fields (same attribute names ``django-filter``/``rest_framework.filters
51
+ .OrderingFilter`` already use, so they look familiar) — any field not
52
+ declared there is silently ignored, on both the filter and the sort
53
+ side. Leaving either one undeclared denies filtering/sorting entirely
54
+ rather than allowing every field by default.
55
+
56
+ Supported filter types
57
+ -----------------------
58
+
59
+ Every filter type Tabulator ships is supported (confirmed against
60
+ ``Filter/defaults/filters.js`` in the Tabulator source for the exact
61
+ set of built-in types):
62
+
63
+ .. list-table::
64
+ :header-rows: 1
65
+
66
+ * - Tabulator ``type``
67
+ - Django lookup
68
+ * - ``=``
69
+ - exact
70
+ * - ``!=``
71
+ - negated exact
72
+ * - ``<``, ``<=``, ``>``, ``>=``
73
+ - ``lt``, ``lte``, ``gt``, ``gte``
74
+ * - ``like``
75
+ - ``icontains``
76
+ * - ``keywords``
77
+ - ``icontains`` (see note below)
78
+ * - ``starts``
79
+ - ``istartswith``
80
+ * - ``ends``
81
+ - ``iendswith``
82
+ * - ``regex``
83
+ - ``regex``
84
+ * - ``in``
85
+ - ``in`` (array value)
86
+ * - ``smart``
87
+ - ported from Tabulator's own ``smart`` filter
88
+ * - ``smarter``
89
+ - ported from Tabulator's own ``smarter`` filter
90
+
91
+ ``keywords`` note: Tabulator's client-side ``keywords`` filter also
92
+ supports a custom word separator and an "all words must match" toggle
93
+ (``headerFilterFuncParams``), but neither is sent to the server in
94
+ remote mode — the ajax payload only ever carries ``{field, type,
95
+ value}``. It is approximated here as a plain substring match, same as
96
+ ``like``.
97
+
98
+ ``smart``/``smarter`` are a faithful port of Tabulator's own filter
99
+ functions, not a Django-specific addition: ``.`` matches any non-empty
100
+ value, ``!`` matches empty/null, a leading comparison operator does a
101
+ numeric comparison, a leading ``=`` does an exact match, multiple
102
+ whitespace-separated words become an ``AND`` of a substring match per
103
+ word, ``AND``/``OR`` combine sub-expressions left to right (no operator
104
+ precedence, same as the original), and anything else falls back to a
105
+ substring match.
106
+
107
+ A value that doesn't fit the field's type (e.g. a non-numeric string
108
+ against an integer field, or an invalid date) raises a DRF
109
+ ``ValidationError`` — a clean ``400`` naming the offending field —
110
+ instead of an unhandled ``500``. Django validates most field types
111
+ eagerly, right when the filter is applied, so this is caught there
112
+ rather than only when the queryset is evaluated.
113
+
114
+ License
115
+ -------
116
+
117
+ MIT — see ``LICENSE``.
118
+
119
+ Development
120
+ -----------
121
+
122
+ .. code-block:: bash
123
+
124
+ pip install -e '.[dev]'
125
+ pytest
126
+
127
+ .. |build-status-image| image:: https://github.com/derafu/djangorestframework-tabulator/actions/workflows/ci.yml/badge.svg
128
+ :target: https://github.com/derafu/djangorestframework-tabulator/actions/workflows/ci.yml
129
+ :alt: CI
130
+
131
+ .. |pypi-version| image:: https://img.shields.io/pypi/v/djangorestframework-tabulator.svg
132
+ :target: https://pypi.org/project/djangorestframework-tabulator/
133
+ :alt: Pypi version
134
+
135
+ .. |py-versions| image:: https://img.shields.io/pypi/pyversions/djangorestframework-tabulator.svg
136
+ :target: https://pypi.org/project/djangorestframework-tabulator/
137
+ :alt: Python versions
@@ -0,0 +1,120 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "djangorestframework-tabulator"
7
+ version = "0.1.0"
8
+ description = "Remote pagination and filtering for Tabulator (tabulator.info) on Django REST Framework."
9
+ readme = "README.rst"
10
+ license = { file = "LICENSE" }
11
+ authors = [
12
+ { name = "Esteban De La Fuente Rubio / Derafu" },
13
+ ]
14
+ requires-python = ">=3.10"
15
+ keywords = ["django", "djangorestframework", "tabulator", "pagination", "filtering"]
16
+ classifiers = [
17
+ "Framework :: Django",
18
+ "Framework :: Django :: 4",
19
+ "Framework :: Django :: 5",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Programming Language :: Python :: 3",
22
+ "Intended Audience :: Developers",
23
+ ]
24
+ dependencies = [
25
+ "django>=4.2",
26
+ "djangorestframework>=3.15",
27
+ ]
28
+
29
+ [project.optional-dependencies]
30
+ dev = [
31
+ "ruff",
32
+ "mypy",
33
+ "django-stubs",
34
+ "djangorestframework-stubs",
35
+ "pytest",
36
+ "pytest-django",
37
+ "pytest-cov",
38
+ "build",
39
+ "twine",
40
+ ]
41
+
42
+ [tool.hatch.build.targets.wheel]
43
+ packages = ["rest_framework_tabulator"]
44
+
45
+ [tool.pytest.ini_options]
46
+ DJANGO_SETTINGS_MODULE = "tests.settings"
47
+ python_files = ["test_*.py"]
48
+ testpaths = ["tests"]
49
+
50
+ [tool.mypy]
51
+ python_version = "3.10"
52
+ strict = true
53
+ files = ["rest_framework_tabulator"]
54
+
55
+ [tool.ruff]
56
+
57
+ include = ["**/*.py", "**/*.pyi"]
58
+
59
+ exclude = [
60
+ ".git",
61
+ "__pycache__",
62
+ ".venv",
63
+ "venv",
64
+ ]
65
+
66
+ line-length = 79
67
+ target-version = "py310"
68
+ respect-gitignore = true
69
+ fix = true
70
+
71
+ [tool.ruff.lint]
72
+
73
+ select = [
74
+ "D",
75
+ "F",
76
+ "E",
77
+ "W",
78
+ "I",
79
+ "UP",
80
+ "N",
81
+ "B",
82
+ "A",
83
+ "C90",
84
+ "ARG",
85
+ "DTZ",
86
+ "TRY",
87
+ "SLF",
88
+ "ERA",
89
+ "PL",
90
+ "RUF",
91
+ "DJ",
92
+ ]
93
+
94
+ ignore = [
95
+ "D100",
96
+ "D101",
97
+ "D102",
98
+ "D104",
99
+ "D105",
100
+ "D106",
101
+ "D203",
102
+ "D212",
103
+ "D401",
104
+ "TRY400",
105
+ "N818",
106
+ "TRY003",
107
+ "ARG001",
108
+ ]
109
+
110
+ [tool.ruff.lint.isort]
111
+ known-first-party = ["rest_framework_tabulator"]
112
+
113
+ [tool.ruff.lint.mccabe]
114
+ max-complexity = 25
115
+
116
+ [tool.ruff.lint.per-file-ignores]
117
+ "tests/**" = ["D", "SLF", "PLR2004"]
118
+
119
+ [tool.ruff.format]
120
+ quote-style = "single"
@@ -0,0 +1,14 @@
1
+ # Copyright (C) 2026 Esteban De La Fuente Rubio / Derafu <https://www.derafu.dev>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ """Tabulator (tabulator.info) adapter for Django REST Framework."""
5
+
6
+ from __future__ import annotations
7
+
8
+ from .filters import TabulatorFilterBackend
9
+ from .pagination import TabulatorPagination
10
+
11
+ __all__ = [
12
+ 'TabulatorFilterBackend',
13
+ 'TabulatorPagination',
14
+ ]