drf-ordering-mapper 0.0.1__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.
- drf_ordering_mapper-0.0.1/LICENSE +19 -0
- drf_ordering_mapper-0.0.1/MANIFEST.in +3 -0
- drf_ordering_mapper-0.0.1/PKG-INFO +114 -0
- drf_ordering_mapper-0.0.1/README.md +89 -0
- drf_ordering_mapper-0.0.1/pyproject.toml +34 -0
- drf_ordering_mapper-0.0.1/setup.cfg +4 -0
- drf_ordering_mapper-0.0.1/src/drf_ordering_mapper/__init__.py +0 -0
- drf_ordering_mapper-0.0.1/src/drf_ordering_mapper/filters.py +75 -0
- drf_ordering_mapper-0.0.1/src/drf_ordering_mapper.egg-info/PKG-INFO +114 -0
- drf_ordering_mapper-0.0.1/src/drf_ordering_mapper.egg-info/SOURCES.txt +10 -0
- drf_ordering_mapper-0.0.1/src/drf_ordering_mapper.egg-info/dependency_links.txt +1 -0
- drf_ordering_mapper-0.0.1/src/drf_ordering_mapper.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2018 The Python Packaging Authority
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: drf-ordering-mapper
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A Django REST Framework filter to map ordering query parameters to ORM fields
|
|
5
|
+
Author: Punyak Goswami
|
|
6
|
+
Project-URL: Homepage, https://github.com/punyak-goswami/drf-ordering-mapper
|
|
7
|
+
Project-URL: Repository, https://github.com/punyak-goswami/drf-ordering-mapper
|
|
8
|
+
Keywords: django,djangorestframework,drf,ordering,filter,api
|
|
9
|
+
Classifier: Framework :: Django
|
|
10
|
+
Classifier: Framework :: Django :: 3
|
|
11
|
+
Classifier: Framework :: Django :: 4
|
|
12
|
+
Classifier: Framework :: Django :: 5
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
+
Classifier: Operating System :: OS Independent
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# drf-ordering-mapper
|
|
27
|
+
|
|
28
|
+
Small utility for Django REST Framework to map ordering query params to actual ORM fields.
|
|
29
|
+
|
|
30
|
+
## Why?
|
|
31
|
+
|
|
32
|
+
DRF’s `OrderingFilter` works well, but you often end up exposing internal field paths like:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
?ordering=company__commodity_name
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
That’s not great for API consumers.
|
|
39
|
+
|
|
40
|
+
This package lets you do:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
?ordering=commodity_name
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
and map it internally.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
pip install drf-ordering-mapper
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from drf_ordering_mapper.filters import OrderingMapperFilter
|
|
62
|
+
|
|
63
|
+
class ProductViewSet(ModelViewSet):
|
|
64
|
+
queryset = Product.objects.all()
|
|
65
|
+
serializer_class = ProductSerializer
|
|
66
|
+
|
|
67
|
+
filter_backends = [OrderingMapperFilter]
|
|
68
|
+
|
|
69
|
+
ordering_fields = ['commodity_name', 'price']
|
|
70
|
+
|
|
71
|
+
ordering_params_mapping = {
|
|
72
|
+
'commodity_name': 'company__commodity_name'
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Example
|
|
79
|
+
|
|
80
|
+
Request:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
GET /api/products?ordering=commodity_name
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Internally becomes:
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
queryset.order_by('company__commodity_name')
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
Descending:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
GET /api/products?ordering=-commodity_name
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
Multiple fields:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
GET /api/products?ordering=commodity_name,-price
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Notes
|
|
111
|
+
|
|
112
|
+
* Works as a drop-in replacement for DRF’s `OrderingFilter`
|
|
113
|
+
* Respects `ordering_fields`
|
|
114
|
+
* Ignores invalid fields (same behavior as DRF)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# drf-ordering-mapper
|
|
2
|
+
|
|
3
|
+
Small utility for Django REST Framework to map ordering query params to actual ORM fields.
|
|
4
|
+
|
|
5
|
+
## Why?
|
|
6
|
+
|
|
7
|
+
DRF’s `OrderingFilter` works well, but you often end up exposing internal field paths like:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
?ordering=company__commodity_name
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
That’s not great for API consumers.
|
|
14
|
+
|
|
15
|
+
This package lets you do:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
?ordering=commodity_name
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
and map it internally.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
pip install drf-ordering-mapper
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from drf_ordering_mapper.filters import OrderingMapperFilter
|
|
37
|
+
|
|
38
|
+
class ProductViewSet(ModelViewSet):
|
|
39
|
+
queryset = Product.objects.all()
|
|
40
|
+
serializer_class = ProductSerializer
|
|
41
|
+
|
|
42
|
+
filter_backends = [OrderingMapperFilter]
|
|
43
|
+
|
|
44
|
+
ordering_fields = ['commodity_name', 'price']
|
|
45
|
+
|
|
46
|
+
ordering_params_mapping = {
|
|
47
|
+
'commodity_name': 'company__commodity_name'
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Example
|
|
54
|
+
|
|
55
|
+
Request:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
GET /api/products?ordering=commodity_name
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Internally becomes:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
queryset.order_by('company__commodity_name')
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
Descending:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
GET /api/products?ordering=-commodity_name
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
Multiple fields:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
GET /api/products?ordering=commodity_name,-price
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Notes
|
|
86
|
+
|
|
87
|
+
* Works as a drop-in replacement for DRF’s `OrderingFilter`
|
|
88
|
+
* Respects `ordering_fields`
|
|
89
|
+
* Ignores invalid fields (same behavior as DRF)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "drf-ordering-mapper"
|
|
7
|
+
version = "0.0.1"
|
|
8
|
+
description = "A Django REST Framework filter to map ordering query parameters to ORM fields"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Punyak Goswami" }
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
keywords = ["django", "djangorestframework", "drf", "ordering", "filter", "api"]
|
|
16
|
+
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Framework :: Django",
|
|
19
|
+
"Framework :: Django :: 3",
|
|
20
|
+
"Framework :: Django :: 4",
|
|
21
|
+
"Framework :: Django :: 5",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.8",
|
|
24
|
+
"Programming Language :: Python :: 3.9",
|
|
25
|
+
"Programming Language :: Python :: 3.10",
|
|
26
|
+
"Programming Language :: Python :: 3.11",
|
|
27
|
+
"Programming Language :: Python :: 3.12",
|
|
28
|
+
"License :: OSI Approved :: MIT License",
|
|
29
|
+
"Operating System :: OS Independent"
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/punyak-goswami/drf-ordering-mapper"
|
|
34
|
+
Repository = "https://github.com/punyak-goswami/drf-ordering-mapper"
|
|
File without changes
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from rest_framework.filters import OrderingFilter
|
|
2
|
+
|
|
3
|
+
class OrderingMapperFilter(OrderingFilter):
|
|
4
|
+
"""
|
|
5
|
+
Extends DRF's OrderingFilter to support mapping of query parameter
|
|
6
|
+
fields to Django ORM field paths.
|
|
7
|
+
|
|
8
|
+
This allows exposing clean, user-friendly ordering parameters in APIs
|
|
9
|
+
while internally using complex or nested model field lookups.
|
|
10
|
+
|
|
11
|
+
Example:
|
|
12
|
+
class ProductViewSet(ModelViewSet):
|
|
13
|
+
filter_backends = [OrderingMapperFilter]
|
|
14
|
+
ordering_fields = ['commodity_name']
|
|
15
|
+
|
|
16
|
+
ordering_params_mapping = {
|
|
17
|
+
'commodity_name': 'company__commodity_name'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
Request:
|
|
21
|
+
GET /api/products?ordering=commodity_name
|
|
22
|
+
GET /api/products?ordering=-commodity_name
|
|
23
|
+
|
|
24
|
+
Attributes:
|
|
25
|
+
ordering_params_mapping (dict):
|
|
26
|
+
Maps query parameter names to Django ORM field paths.
|
|
27
|
+
"""
|
|
28
|
+
def get_ordering(self, request, queryset, view):
|
|
29
|
+
params = request.query_params.get(self.ordering_param)
|
|
30
|
+
ordering_params_mapping = getattr(view, 'ordering_params_mapping', {})
|
|
31
|
+
|
|
32
|
+
if params:
|
|
33
|
+
fields = []
|
|
34
|
+
for param in params.split(','):
|
|
35
|
+
param = param.strip()
|
|
36
|
+
if param.startswith('-'):
|
|
37
|
+
param = "-" + ordering_params_mapping.get(param[1:]) if param[1:] in ordering_params_mapping else param
|
|
38
|
+
else:
|
|
39
|
+
param = ordering_params_mapping.get(param) if param in ordering_params_mapping else param
|
|
40
|
+
if param:
|
|
41
|
+
fields.append(param.strip())
|
|
42
|
+
|
|
43
|
+
ordering = self.remove_invalid_fields(queryset, fields, view, request)
|
|
44
|
+
|
|
45
|
+
if ordering:
|
|
46
|
+
return ordering
|
|
47
|
+
|
|
48
|
+
# No ordering was included, or all the ordering fields were invalid
|
|
49
|
+
return self.get_default_ordering(view)
|
|
50
|
+
|
|
51
|
+
def get_valid_fields(self, queryset, view, context={}):
|
|
52
|
+
valid_fields = getattr(view, 'ordering_fields', self.ordering_fields)
|
|
53
|
+
ordering_params_mapping = getattr(view, 'ordering_params_mapping', {})
|
|
54
|
+
if valid_fields:
|
|
55
|
+
valid_fields = [ordering_params_mapping.get(field) if field in ordering_params_mapping else field for field in valid_fields]
|
|
56
|
+
if valid_fields is None:
|
|
57
|
+
# Default to allowing filtering on serializer fields
|
|
58
|
+
return self.get_default_valid_fields(queryset, view, context)
|
|
59
|
+
|
|
60
|
+
elif valid_fields == '__all__':
|
|
61
|
+
# View explicitly allows filtering on any model field
|
|
62
|
+
valid_fields = [
|
|
63
|
+
(field.name, field.verbose_name) for field in queryset.model._meta.fields
|
|
64
|
+
]
|
|
65
|
+
valid_fields += [
|
|
66
|
+
(key, key.title().split('__'))
|
|
67
|
+
for key in queryset.query.annotations
|
|
68
|
+
]
|
|
69
|
+
else:
|
|
70
|
+
valid_fields = [
|
|
71
|
+
(item, item) if isinstance(item, str) else item
|
|
72
|
+
for item in valid_fields
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
return valid_fields
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: drf-ordering-mapper
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A Django REST Framework filter to map ordering query parameters to ORM fields
|
|
5
|
+
Author: Punyak Goswami
|
|
6
|
+
Project-URL: Homepage, https://github.com/punyak-goswami/drf-ordering-mapper
|
|
7
|
+
Project-URL: Repository, https://github.com/punyak-goswami/drf-ordering-mapper
|
|
8
|
+
Keywords: django,djangorestframework,drf,ordering,filter,api
|
|
9
|
+
Classifier: Framework :: Django
|
|
10
|
+
Classifier: Framework :: Django :: 3
|
|
11
|
+
Classifier: Framework :: Django :: 4
|
|
12
|
+
Classifier: Framework :: Django :: 5
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
+
Classifier: Operating System :: OS Independent
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# drf-ordering-mapper
|
|
27
|
+
|
|
28
|
+
Small utility for Django REST Framework to map ordering query params to actual ORM fields.
|
|
29
|
+
|
|
30
|
+
## Why?
|
|
31
|
+
|
|
32
|
+
DRF’s `OrderingFilter` works well, but you often end up exposing internal field paths like:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
?ordering=company__commodity_name
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
That’s not great for API consumers.
|
|
39
|
+
|
|
40
|
+
This package lets you do:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
?ordering=commodity_name
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
and map it internally.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
pip install drf-ordering-mapper
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from drf_ordering_mapper.filters import OrderingMapperFilter
|
|
62
|
+
|
|
63
|
+
class ProductViewSet(ModelViewSet):
|
|
64
|
+
queryset = Product.objects.all()
|
|
65
|
+
serializer_class = ProductSerializer
|
|
66
|
+
|
|
67
|
+
filter_backends = [OrderingMapperFilter]
|
|
68
|
+
|
|
69
|
+
ordering_fields = ['commodity_name', 'price']
|
|
70
|
+
|
|
71
|
+
ordering_params_mapping = {
|
|
72
|
+
'commodity_name': 'company__commodity_name'
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Example
|
|
79
|
+
|
|
80
|
+
Request:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
GET /api/products?ordering=commodity_name
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Internally becomes:
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
queryset.order_by('company__commodity_name')
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
Descending:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
GET /api/products?ordering=-commodity_name
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
Multiple fields:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
GET /api/products?ordering=commodity_name,-price
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Notes
|
|
111
|
+
|
|
112
|
+
* Works as a drop-in replacement for DRF’s `OrderingFilter`
|
|
113
|
+
* Respects `ordering_fields`
|
|
114
|
+
* Ignores invalid fields (same behavior as DRF)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
MANIFEST.in
|
|
3
|
+
README.md
|
|
4
|
+
pyproject.toml
|
|
5
|
+
src/drf_ordering_mapper/__init__.py
|
|
6
|
+
src/drf_ordering_mapper/filters.py
|
|
7
|
+
src/drf_ordering_mapper.egg-info/PKG-INFO
|
|
8
|
+
src/drf_ordering_mapper.egg-info/SOURCES.txt
|
|
9
|
+
src/drf_ordering_mapper.egg-info/dependency_links.txt
|
|
10
|
+
src/drf_ordering_mapper.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
drf_ordering_mapper
|