Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 81d2236

Browse files
authored
JSONAPIOrderingFilter (#459)
JSONAPIOrderingFilter includes @sliverc review requested changes - use json instead of yaml fixture to remove dependency on PyYAML - use reverse() - request.data dict instead of string concat to the url - response.json() instead of json.loads(response.content.decode(...)
1 parent 95e6d8d commit 81d2236

File tree

8 files changed

+407
-9
lines changed

8 files changed

+407
-9
lines changed

‎CHANGELOG.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
[unreleased]
22

33
* Add testing configuration to `REST_FRAMEWORK` configuration as described in [DRF](https://www.django-rest-framework.org/api-guide/testing/#configuration)
4-
* Add sorting configuration to `REST_FRAMEWORK` as defined in [json api spec](http://jsonapi.org/format/#fetching-sorting)
54
* Add `HyperlinkedRelatedField` and `SerializerMethodHyperlinkedRelatedField`. See [usage docs](docs/usage.md#related-fields)
65
* Add related urls support. See [usage docs](docs/usage.md#related-urls)
76
* Replaced binary `drf_example` sqlite3 db with a [fixture](example/fixtures/drf_example.yaml). See [usage docs](docs/usage.md#running-the-example-app).
8-
7+
* Add optional [jsonapi-style](http://jsonapi.org/format/) sort filter backend. See [usage docs](docs/usage.md#filter-backends)
98

109
v2.5.0 - Released July 11, 2018
1110

‎README.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,8 @@ override ``settings.REST_FRAMEWORK``
173173
),
174174
'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata',
175175
'DEFAULT_FILTER_BACKENDS': (
176-
'rest_framework.filters.OrderingFilter',
176+
'rest_framework_json_api.backends.JSONAPIOrderingFilter',
177177
),
178-
'ORDERING_PARAM': 'sort',
179178
'TEST_REQUEST_RENDERER_CLASSES': (
180179
'rest_framework_json_api.renderers.JSONRenderer',
181180
),

‎docs/usage.md

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11

22
# Usage
33

4-
The DJA package implements a custom renderer, parser, exception handler, and
4+
The DJA package implements a custom renderer, parser, exception handler, query filter backends, and
55
pagination. To get started enable the pieces in `settings.py` that you want to use.
66

7-
Many features of the JSON:API format standard have been implemented using Mixin classes in `serializers.py`.
7+
Many features of the [JSON:API](http://jsonapi.org/format) format standard have been implemented using
8+
Mixin classes in `serializers.py`.
89
The easiest way to make use of those features is to import ModelSerializer variants
910
from `rest_framework_json_api` instead of the usual `rest_framework`
1011

@@ -32,9 +33,8 @@ REST_FRAMEWORK = {
3233
),
3334
'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata',
3435
'DEFAULT_FILTER_BACKENDS': (
35-
'rest_framework.filters.OrderingFilter',
36+
'rest_framework_json_api.backends.JSONAPIOrderingFilter',
3637
),
37-
'ORDERING_PARAM': 'sort',
3838
'TEST_REQUEST_RENDERER_CLASSES': (
3939
'rest_framework_json_api.renderers.JSONRenderer',
4040
),
@@ -90,6 +90,35 @@ class MyLimitPagination(JsonApiLimitOffsetPagination):
9090
max_limit = None
9191
```
9292

93+
### Filter Backends
94+
95+
_This is the first of several anticipated JSON:API-specific filter backends._
96+
97+
#### `JSONAPIOrderingFilter`
98+
`JSONAPIOrderingFilter` implements the [JSON:API `sort`](http://jsonapi.org/format/#fetching-sorting) and uses
99+
DRF's [ordering filter](http://django-rest-framework.readthedocs.io/en/latest/api-guide/filtering/#orderingfilter).
100+
101+
Per the JSON:API, "If the server does not support sorting as specified in the query parameter `sort`,
102+
it **MUST** return `400 Bad Request`." For example, for `?sort=`abc,foo,def` where `foo` is a valid
103+
field name and the other two are not valid:
104+
```json
105+
{
106+
"errors": [
107+
{
108+
"detail": "invalid sort parameters: abc,def",
109+
"source": {
110+
"pointer": "/data"
111+
},
112+
"status": "400"
113+
}
114+
]
115+
}
116+
```
117+
118+
If you want to silently ignore bad sort fields, just use `rest_framework.filters.OrderingFilter` and set
119+
`ordering_param` to `sort`.
120+
121+
93122
### Performance Testing
94123

95124
If you are trying to see if your viewsets are configured properly to optimize performance,

‎example/fixtures/blogentry.json

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
[
2+
{
3+
"model": "example.blog",
4+
"pk": 1,
5+
"fields": {
6+
"created_at": "2018年08月20日T00:00:00",
7+
"modified_at": "2018年08月20日T00:00:00",
8+
"name": "ANTB",
9+
"tagline": "ANTHROPOLOGY (BARNARD)"
10+
}
11+
},
12+
{
13+
"model": "example.blog",
14+
"pk": 2,
15+
"fields": {
16+
"created_at": "2018年08月20日T00:00:00",
17+
"modified_at": "2018年08月20日T00:00:00",
18+
"name": "CLSB",
19+
"tagline": "CLASSICS (BARNARD)"
20+
}
21+
},
22+
{
23+
"model": "example.blog",
24+
"pk": 3,
25+
"fields": {
26+
"created_at": "2018年08月20日T00:00:00",
27+
"modified_at": "2018年08月20日T00:00:00",
28+
"name": "AMSB",
29+
"tagline": "AMERICAN STUDIES (BARNARD)"
30+
}
31+
},
32+
{
33+
"model": "example.blog",
34+
"pk": 4,
35+
"fields": {
36+
"created_at": "2018年08月20日T00:00:00",
37+
"modified_at": "2018年08月20日T00:00:00",
38+
"name": "CHMB",
39+
"tagline": "CHEMISTRY (BARNARD)"
40+
}
41+
},
42+
{
43+
"model": "example.blog",
44+
"pk": 5,
45+
"fields": {
46+
"created_at": "2018年08月20日T00:00:00",
47+
"modified_at": "2018年08月20日T00:00:00",
48+
"name": "ARHB",
49+
"tagline": "ART HISTORY (BARNARD)"
50+
}
51+
},
52+
{
53+
"model": "example.blog",
54+
"pk": 6,
55+
"fields": {
56+
"created_at": "2018年08月20日T00:00:00",
57+
"modified_at": "2018年08月20日T00:00:00",
58+
"name": "ITLB",
59+
"tagline": "ITALIAN (BARNARD)"
60+
}
61+
},
62+
{
63+
"model": "example.blog",
64+
"pk": 7,
65+
"fields": {
66+
"created_at": "2018年08月20日T00:00:00",
67+
"modified_at": "2018年08月20日T00:00:00",
68+
"name": "BIOB",
69+
"tagline": "BIOLOGICAL SCIENCES (BARNARD)"
70+
}
71+
},
72+
{
73+
"model": "example.entry",
74+
"pk": 1,
75+
"fields": {
76+
"created_at": "2018年08月20日T00:00:00",
77+
"modified_at": "2018年08月20日T00:00:00",
78+
"blog": 1,
79+
"headline": "ANTH1009V",
80+
"body_text": "INTRO TO LANGUAGE & CULTURE",
81+
"pub_date": null,
82+
"mod_date": null,
83+
"n_comments": 0,
84+
"n_pingbacks": 0,
85+
"rating": 0,
86+
"authors": [
87+
1
88+
]
89+
}
90+
},
91+
{
92+
"model": "example.entry",
93+
"pk": 2,
94+
"fields": {
95+
"created_at": "2018年08月20日T00:00:00",
96+
"modified_at": "2018年08月20日T00:00:00",
97+
"blog": 2,
98+
"headline": "CLCV2442V",
99+
"body_text": "EGYPT IN CLASSICAL WORLD-DISC",
100+
"pub_date": null,
101+
"mod_date": null,
102+
"n_comments": 0,
103+
"n_pingbacks": 0,
104+
"rating": 0,
105+
"authors": [
106+
2
107+
]
108+
}
109+
},
110+
{
111+
"model": "example.entry",
112+
"pk": 3,
113+
"fields": {
114+
"created_at": "2018年08月20日T00:00:00",
115+
"modified_at": "2018年08月20日T00:00:00",
116+
"blog": 3,
117+
"headline": "AMST3704X",
118+
"body_text": "SENIOR RESEARCH ESSAY SEMINAR",
119+
"pub_date": null,
120+
"mod_date": null,
121+
"n_comments": 0,
122+
"n_pingbacks": 0,
123+
"rating": 0,
124+
"authors": []
125+
}
126+
},
127+
{
128+
"model": "example.entry",
129+
"pk": 4,
130+
"fields": {
131+
"created_at": "2018年08月20日T00:00:00",
132+
"modified_at": "2018年08月20日T00:00:00",
133+
"blog": 1,
134+
"headline": "ANTH3976V",
135+
"body_text": "ANTHROPOLOGY OF SCIENCE",
136+
"pub_date": null,
137+
"mod_date": null,
138+
"n_comments": 0,
139+
"n_pingbacks": 0,
140+
"rating": 0,
141+
"authors": []
142+
}
143+
},
144+
{
145+
"model": "example.entry",
146+
"pk": 5,
147+
"fields": {
148+
"created_at": "2018年08月20日T00:00:00",
149+
"modified_at": "2018年08月20日T00:00:00",
150+
"blog": 4,
151+
"headline": "CHEM3271X",
152+
"body_text": "INORGANIC CHEMISTRY",
153+
"pub_date": null,
154+
"mod_date": null,
155+
"n_comments": 0,
156+
"n_pingbacks": 0,
157+
"rating": 0,
158+
"authors": []
159+
}
160+
},
161+
{
162+
"model": "example.entry",
163+
"pk": 6,
164+
"fields": {
165+
"created_at": "2018年08月20日T00:00:00",
166+
"modified_at": "2018年08月20日T00:00:00",
167+
"blog": 5,
168+
"headline": "AHIS3915X",
169+
"body_text": "ISLAM AND MEDIEVAL WEST",
170+
"pub_date": null,
171+
"mod_date": null,
172+
"n_comments": 0,
173+
"n_pingbacks": 0,
174+
"rating": 0,
175+
"authors": []
176+
}
177+
},
178+
{
179+
"model": "example.entry",
180+
"pk": 7,
181+
"fields": {
182+
"created_at": "2018年08月20日T00:00:00",
183+
"modified_at": "2018年08月20日T00:00:00",
184+
"blog": 1,
185+
"headline": "ANTH3868X",
186+
"body_text": "ETHNOGRAPHIC FIELD RESEARCH IN NYC",
187+
"pub_date": null,
188+
"mod_date": null,
189+
"n_comments": 0,
190+
"n_pingbacks": 0,
191+
"rating": 0,
192+
"authors": []
193+
}
194+
},
195+
{
196+
"model": "example.entry",
197+
"pk": 8,
198+
"fields": {
199+
"created_at": "2018年08月20日T00:00:00",
200+
"modified_at": "2018年08月20日T00:00:00",
201+
"blog": 6,
202+
"headline": "CLIA3660V",
203+
"body_text": "MAFIA MOVIES",
204+
"pub_date": null,
205+
"mod_date": null,
206+
"n_comments": 0,
207+
"n_pingbacks": 0,
208+
"rating": 0,
209+
"authors": []
210+
}
211+
},
212+
{
213+
"model": "example.entry",
214+
"pk": 9,
215+
"fields": {
216+
"created_at": "2018年08月20日T00:00:00",
217+
"modified_at": "2018年08月20日T00:00:00",
218+
"blog": 5,
219+
"headline": "AHIS3999X",
220+
"body_text": "INDEPENDENT RESEARCH",
221+
"pub_date": null,
222+
"mod_date": null,
223+
"n_comments": 0,
224+
"n_pingbacks": 0,
225+
"rating": 0,
226+
"authors": []
227+
}
228+
},
229+
{
230+
"model": "example.entry",
231+
"pk": 10,
232+
"fields": {
233+
"created_at": "2018年08月20日T00:00:00",
234+
"modified_at": "2018年08月20日T00:00:00",
235+
"blog": 7,
236+
"headline": "BIOL3594X",
237+
"body_text": "SENIOR THESIS SEMINAR",
238+
"pub_date": null,
239+
"mod_date": null,
240+
"n_comments": 0,
241+
"n_pingbacks": 0,
242+
"rating": 0,
243+
"authors": []
244+
}
245+
},
246+
{
247+
"model": "example.entry",
248+
"pk": 11,
249+
"fields": {
250+
"created_at": "2018年08月20日T00:00:00",
251+
"modified_at": "2018年08月20日T00:00:00",
252+
"blog": 7,
253+
"headline": "BIOL9999X",
254+
"body_text": null,
255+
"pub_date": null,
256+
"mod_date": null,
257+
"n_comments": 0,
258+
"n_pingbacks": 0,
259+
"rating": 0,
260+
"authors": []
261+
}
262+
},
263+
{
264+
"model": "example.entry",
265+
"pk": 12,
266+
"fields": {
267+
"created_at": "2018年08月20日T00:00:00",
268+
"modified_at": "2018年08月20日T00:00:00",
269+
"blog": 7,
270+
"headline": "BIOL0000X",
271+
"body_text": "",
272+
"pub_date": null,
273+
"mod_date": null,
274+
"n_comments": 0,
275+
"n_pingbacks": 0,
276+
"rating": 0,
277+
"authors": []
278+
}
279+
}
280+
]

‎example/settings/dev.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
),
9090
'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata',
9191
'DEFAULT_FILTER_BACKENDS': (
92-
'rest_framework.filters.OrderingFilter',
92+
'rest_framework_json_api.backends.JSONAPIOrderingFilter',
9393
),
9494
'ORDERING_PARAM': 'sort',
9595
'TEST_REQUEST_RENDERER_CLASSES': (

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /