0
# Views
1
2
Enhanced Django REST framework views with JSON:API features including automatic include parameter handling, relationship views, prefetching optimization, and JSON:API response formatting.
3
4
## Capabilities
5
6
### ModelViewSet
7
8
Enhanced ModelViewSet with JSON:API features and automatic optimization.
9
10
```python { .api }
11
class ModelViewSet(PreloadIncludesMixin, viewsets.ModelViewSet):
12
"""
13
JSON:API compatible ModelViewSet with automatic include handling and optimization.
14
15
Inherits all Django REST framework ModelViewSet functionality while adding:
16
- Automatic prefetching based on include parameter
17
- JSON:API response formatting
18
- Relationship endpoint support
19
- Resource type detection
20
"""
21
22
queryset = None # QuerySet for this viewset
23
serializer_class = None # Serializer class
24
resource_name = None # Override resource type name
25
26
# Optimization configuration
27
prefetch_for_includes = {} # Prefetch config for include paths
28
select_for_includes = {} # Select_related config for include paths
29
```
30
31
Usage example:
32
33
```python
34
from rest_framework_json_api import views
35
from myapp.models import Article
36
from myapp.serializers import ArticleSerializer
37
38
class ArticleViewSet(views.ModelViewSet):
39
queryset = Article.objects.all()
40
serializer_class = ArticleSerializer
41
42
# Optimize queries for common includes
43
prefetch_for_includes = {
44
'__all__': [], # Always prefetch these
45
'author': ['author'],
46
'comments': ['comments'],
47
'comments.user': ['comments__user']
48
}
49
50
select_for_includes = {
51
'author': ['author'],
52
'category': ['category']
53
}
54
55
# Automatically handles: GET /articles?include=author,comments
56
# And optimizes database queries accordingly
57
```
58
59
### ReadOnlyModelViewSet
60
61
Read-only version of ModelViewSet for read-only API endpoints.
62
63
```python { .api }
64
class ReadOnlyModelViewSet(PreloadIncludesMixin, viewsets.ReadOnlyModelViewSet):
65
"""
66
JSON:API compatible ReadOnlyModelViewSet.
67
68
Provides list and retrieve actions only with JSON:API features:
69
- Include parameter support
70
- Automatic query optimization
71
- JSON:API response formatting
72
"""
73
74
queryset = None
75
serializer_class = None
76
resource_name = None
77
```
78
79
### RelationshipView
80
81
Specialized view for JSON:API relationship endpoints.
82
83
```python { .api }
84
class RelationshipView(generics.GenericAPIView):
85
"""
86
View for JSON:API relationship endpoints.
87
88
Handles relationship manipulation endpoints like:
89
- GET /articles/1/relationships/author
90
- POST /articles/1/relationships/tags
91
- PATCH /articles/1/relationships/author
92
- DELETE /articles/1/relationships/tags
93
"""
94
95
queryset = None
96
serializer_class = None
97
related_field = None # Name of the related field
98
99
def get(self, request, *args, **kwargs):
100
"""Get relationship data."""
101
102
def post(self, request, *args, **kwargs):
103
"""Add to relationship (for to-many relationships)."""
104
105
def patch(self, request, *args, **kwargs):
106
"""Replace relationship data."""
107
108
def delete(self, request, *args, **kwargs):
109
"""Remove from relationship (for to-many relationships)."""
110
```
111
112
Usage example:
113
114
```python
115
from django.urls import path
116
from rest_framework_json_api.views import RelationshipView
117
118
class ArticleAuthorRelationshipView(RelationshipView):
119
queryset = Article.objects.all()
120
related_field = 'author'
121
122
# In urls.py:
123
urlpatterns = [
124
path('articles/<int:pk>/relationships/author/',
125
ArticleAuthorRelationshipView.as_view()),
126
]
127
```
128
129
### RelatedMixin
130
131
Base mixin that provides related field handling functionality.
132
133
```python { .api }
134
class RelatedMixin:
135
"""
136
Base mixin for handling related field operations in JSON:API views.
137
138
Provides utilities for getting related instances and handling
139
relationship operations.
140
"""
141
142
def get_related_instance(self):
143
"""Get related instance for relationship operations."""
144
145
def get_relation_instance(self, resource_instance, source, serializer):
146
"""Get specific relation instance from resource."""
147
```
148
149
### PreloadIncludesMixin
150
151
Mixin that provides automatic query optimization based on include parameters.
152
153
```python { .api }
154
class PreloadIncludesMixin:
155
"""
156
Mixin for automatic query optimization based on include parameter.
157
158
Configuration attributes:
159
- prefetch_for_includes: Dict mapping include paths to prefetch_related() args
160
- select_for_includes: Dict mapping include paths to select_related() args
161
162
Special key '__all__' applies to all requests regardless of include parameter.
163
"""
164
165
prefetch_for_includes = {} # Include path -> prefetch list mapping
166
select_for_includes = {} # Include path -> select_related list mapping
167
168
def get_select_related(self, include):
169
"""
170
Get select_related args for an include path.
171
172
Args:
173
include: Include path string (e.g., 'author', 'comments.user')
174
175
Returns:
176
list or None: Arguments for select_related()
177
"""
178
179
def get_prefetch_related(self, include):
180
"""
181
Get prefetch_related args for an include path.
182
183
Args:
184
include: Include path string
185
186
Returns:
187
list or None: Arguments for prefetch_related()
188
"""
189
190
def get_queryset(self, *args, **kwargs):
191
"""
192
Enhanced get_queryset with automatic optimization.
193
194
Analyzes include parameter and applies appropriate
195
select_related and prefetch_related optimizations.
196
"""
197
```
198
199
Usage example:
200
201
```python
202
class ArticleViewSet(PreloadIncludesMixin, viewsets.ModelViewSet):
203
queryset = Article.objects.all()
204
serializer_class = ArticleSerializer
205
206
# When ?include=author is requested, select_related('author')
207
select_for_includes = {
208
'author': ['author'],
209
'category': ['category'],
210
'author.profile': ['author__profile']
211
}
212
213
# When ?include=comments is requested, prefetch_related('comments')
214
prefetch_for_includes = {
215
'comments': ['comments'],
216
'tags': ['tags'],
217
'comments.user': ['comments__user']
218
}
219
```
220
221
### AutoPrefetchMixin
222
223
Mixin that automatically detects and prefetches relationships.
224
225
```python { .api }
226
class AutoPrefetchMixin:
227
"""
228
Mixin for automatic prefetching of OneToOne and ManyToMany relationships.
229
230
Automatically analyzes include parameter and applies appropriate
231
prefetching for detected relationship types without manual configuration.
232
"""
233
234
def get_queryset(self, *args, **kwargs):
235
"""
236
Enhanced get_queryset with automatic relationship detection.
237
238
Automatically detects relationship types and applies:
239
- select_related for ForeignKey and OneToOne
240
- prefetch_related for ManyToMany and reverse ForeignKey
241
"""
242
```
243
244
## Include Parameter Support
245
246
Views automatically handle the JSON:API include parameter:
247
248
```python
249
# GET /articles?include=author,comments,tags
250
# Automatically includes related resources in response:
251
{
252
"data": [{
253
"type": "articles",
254
"id": "1",
255
"relationships": {
256
"author": {"data": {"type": "authors", "id": "5"}},
257
"comments": {"data": [{"type": "comments", "id": "10"}]},
258
"tags": {"data": [{"type": "tags", "id": "2"}]}
259
}
260
}],
261
"included": [
262
{"type": "authors", "id": "5", "attributes": {...}},
263
{"type": "comments", "id": "10", "attributes": {...}},
264
{"type": "tags", "id": "2", "attributes": {...}}
265
]
266
}
267
```
268
269
## Query Optimization
270
271
Views provide sophisticated query optimization:
272
273
```python
274
class ArticleViewSet(views.ModelViewSet):
275
queryset = Article.objects.all()
276
277
# Manual optimization configuration
278
prefetch_for_includes = {
279
'__all__': ['tags'], # Always prefetch tags
280
'author': ['author'],
281
'comments': ['comments'],
282
'comments.user': ['comments__user'],
283
'category.section': ['category'] # Nested relationships
284
}
285
286
select_for_includes = {
287
'author': ['author', 'author__profile'],
288
'category': ['category'],
289
'category.parent': ['category__parent']
290
}
291
292
# Or use AutoPrefetchMixin for automatic detection:
293
class ArticleViewSet(AutoPrefetchMixin, views.ModelViewSet):
294
queryset = Article.objects.all()
295
# No manual configuration needed
296
```
297
298
## Resource Name Customization
299
300
Views support custom resource names:
301
302
```python
303
class ArticleViewSet(views.ModelViewSet):
304
queryset = Article.objects.all()
305
resource_name = 'blog-posts' # Override default 'articles'
306
307
# Results in resource type 'blog-posts' instead of 'articles'
308
```
309
310
## Error Handling
311
312
Views integrate with JSON:API error formatting:
313
314
```python
315
# 404 errors become:
316
{
317
"errors": [{
318
"status": "404",
319
"detail": "Not found."
320
}]
321
}
322
323
# Validation errors become:
324
{
325
"errors": [{
326
"status": "400",
327
"detail": "This field is required.",
328
"source": {"pointer": "/data/attributes/title"}
329
}]
330
}
331
```
332
333
## Types
334
335
```python { .api }
336
from rest_framework_json_api.views import (
337
ModelViewSet,
338
ReadOnlyModelViewSet,
339
RelationshipView,
340
PreloadIncludesMixin,
341
AutoPrefetchMixin
342
)
343
344
# Base classes from Django REST framework
345
from rest_framework import viewsets, generics
346
```