0
# Generic Views and Mixins
1
2
Pre-built generic views and mixins for common API patterns. Provides CRUD operations, pagination, and filtering with minimal code by combining the power of Django's class-based views with DRF's API functionality.
3
4
## Capabilities
5
6
### Generic API View Base
7
8
Base class for all generic views providing common functionality.
9
10
```python { .api }
11
class GenericAPIView(APIView):
12
"""
13
Base class for generic views with queryset and serializer support.
14
"""
15
queryset = None # Base queryset for the view
16
serializer_class = None # Serializer class to use
17
lookup_field = 'pk' # Field for object lookup
18
lookup_url_kwarg = None # URL kwarg for lookup
19
filter_backends = [] # List of filter backend classes
20
pagination_class = None # Pagination class
21
22
def get_queryset(self):
23
"""
24
Get the queryset for this view.
25
26
Returns:
27
QuerySet: Filtered queryset
28
"""
29
30
def get_object(self):
31
"""
32
Get single object based on lookup parameters.
33
34
Returns:
35
Model instance
36
37
Raises:
38
Http404: If object not found
39
"""
40
41
def get_serializer(self, *args, **kwargs):
42
"""
43
Get serializer instance with current context.
44
45
Returns:
46
Serializer: Configured serializer instance
47
"""
48
49
def get_serializer_class(self):
50
"""
51
Get serializer class for this view.
52
53
Returns:
54
Serializer class
55
"""
56
57
def paginate_queryset(self, queryset):
58
"""
59
Paginate queryset if pagination is configured.
60
61
Args:
62
queryset: QuerySet to paginate
63
64
Returns:
65
list or None: Paginated results
66
"""
67
68
def filter_queryset(self, queryset):
69
"""
70
Apply filtering backends to queryset.
71
72
Args:
73
queryset: Base queryset
74
75
Returns:
76
QuerySet: Filtered queryset
77
"""
78
```
79
80
### Single Object Generic Views
81
82
Views for operations on individual objects.
83
84
```python { .api }
85
class CreateAPIView(GenericAPIView):
86
"""
87
Concrete view for creating model instances.
88
"""
89
def post(self, request, *args, **kwargs):
90
"""
91
Handle POST requests to create new objects.
92
93
Returns:
94
Response: 201 Created with serialized data
95
"""
96
97
class RetrieveAPIView(GenericAPIView):
98
"""
99
Concrete view for retrieving model instances.
100
"""
101
def get(self, request, *args, **kwargs):
102
"""
103
Handle GET requests to retrieve single object.
104
105
Returns:
106
Response: 200 OK with serialized data
107
"""
108
109
class UpdateAPIView(GenericAPIView):
110
"""
111
Concrete view for updating model instances.
112
"""
113
def put(self, request, *args, **kwargs):
114
"""
115
Handle PUT requests for full object updates.
116
117
Returns:
118
Response: 200 OK with updated serialized data
119
"""
120
121
def patch(self, request, *args, **kwargs):
122
"""
123
Handle PATCH requests for partial object updates.
124
125
Returns:
126
Response: 200 OK with updated serialized data
127
"""
128
129
class DestroyAPIView(GenericAPIView):
130
"""
131
Concrete view for deleting model instances.
132
"""
133
def delete(self, request, *args, **kwargs):
134
"""
135
Handle DELETE requests to destroy objects.
136
137
Returns:
138
Response: 204 No Content
139
"""
140
```
141
142
### List Generic Views
143
144
Views for operations on collections of objects.
145
146
```python { .api }
147
class ListAPIView(GenericAPIView):
148
"""
149
Concrete view for listing model instances.
150
"""
151
def get(self, request, *args, **kwargs):
152
"""
153
Handle GET requests to list objects with pagination and filtering.
154
155
Returns:
156
Response: 200 OK with serialized data list
157
"""
158
```
159
160
### Combined Generic Views
161
162
Views that combine multiple operations for convenience.
163
164
```python { .api }
165
class ListCreateAPIView(GenericAPIView):
166
"""
167
Concrete view for listing and creating model instances.
168
"""
169
def get(self, request, *args, **kwargs):
170
"""List objects."""
171
172
def post(self, request, *args, **kwargs):
173
"""Create new object."""
174
175
class RetrieveUpdateAPIView(GenericAPIView):
176
"""
177
Concrete view for retrieving and updating model instances.
178
"""
179
def get(self, request, *args, **kwargs):
180
"""Retrieve object."""
181
182
def put(self, request, *args, **kwargs):
183
"""Update object (full)."""
184
185
def patch(self, request, *args, **kwargs):
186
"""Update object (partial)."""
187
188
class RetrieveDestroyAPIView(GenericAPIView):
189
"""
190
Concrete view for retrieving and deleting model instances.
191
"""
192
def get(self, request, *args, **kwargs):
193
"""Retrieve object."""
194
195
def delete(self, request, *args, **kwargs):
196
"""Delete object."""
197
198
class RetrieveUpdateDestroyAPIView(GenericAPIView):
199
"""
200
Concrete view for retrieving, updating, and deleting model instances.
201
"""
202
def get(self, request, *args, **kwargs):
203
"""Retrieve object."""
204
205
def put(self, request, *args, **kwargs):
206
"""Update object (full)."""
207
208
def patch(self, request, *args, **kwargs):
209
"""Update object (partial)."""
210
211
def delete(self, request, *args, **kwargs):
212
"""Delete object."""
213
```
214
215
### Model Mixins
216
217
Modular functionality that can be mixed into views.
218
219
```python { .api }
220
class CreateModelMixin:
221
"""
222
Provide create functionality for views.
223
"""
224
def create(self, request, *args, **kwargs):
225
"""
226
Create new model instance.
227
228
Returns:
229
Response: 201 Created with serialized data
230
"""
231
232
def perform_create(self, serializer):
233
"""
234
Save the object during creation.
235
236
Args:
237
serializer: Validated serializer instance
238
"""
239
serializer.save()
240
241
def get_success_headers(self, data):
242
"""
243
Get headers for successful creation response.
244
245
Args:
246
data: Serialized object data
247
248
Returns:
249
dict: Response headers
250
"""
251
252
class ListModelMixin:
253
"""
254
Provide list functionality for views.
255
"""
256
def list(self, request, *args, **kwargs):
257
"""
258
List model instances with pagination and filtering.
259
260
Returns:
261
Response: 200 OK with serialized data list
262
"""
263
264
class RetrieveModelMixin:
265
"""
266
Provide retrieve functionality for views.
267
"""
268
def retrieve(self, request, *args, **kwargs):
269
"""
270
Retrieve single model instance.
271
272
Returns:
273
Response: 200 OK with serialized data
274
"""
275
276
class UpdateModelMixin:
277
"""
278
Provide update functionality for views.
279
"""
280
def update(self, request, *args, **kwargs):
281
"""
282
Update model instance (full update).
283
284
Returns:
285
Response: 200 OK with serialized data
286
"""
287
288
def partial_update(self, request, *args, **kwargs):
289
"""
290
Partially update model instance.
291
292
Returns:
293
Response: 200 OK with serialized data
294
"""
295
296
def perform_update(self, serializer):
297
"""
298
Save the object during update.
299
300
Args:
301
serializer: Validated serializer instance
302
"""
303
serializer.save()
304
305
class DestroyModelMixin:
306
"""
307
Provide destroy functionality for views.
308
"""
309
def destroy(self, request, *args, **kwargs):
310
"""
311
Delete model instance.
312
313
Returns:
314
Response: 204 No Content
315
"""
316
317
def perform_destroy(self, instance):
318
"""
319
Delete the object.
320
321
Args:
322
instance: Object instance to delete
323
"""
324
instance.delete()
325
```
326
327
## Usage Examples
328
329
### Simple Generic Views
330
331
```python
332
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
333
from rest_framework.permissions import IsAuthenticated
334
335
class BookListCreateView(ListCreateAPIView):
336
queryset = Book.objects.all()
337
serializer_class = BookSerializer
338
permission_classes = [IsAuthenticated]
339
340
def perform_create(self, serializer):
341
# Automatically set owner to current user
342
serializer.save(owner=self.request.user)
343
344
class BookDetailView(RetrieveUpdateDestroyAPIView):
345
queryset = Book.objects.all()
346
serializer_class = BookSerializer
347
permission_classes = [IsAuthenticated]
348
349
def perform_update(self, serializer):
350
# Custom logic during update
351
serializer.save(last_modified_by=self.request.user)
352
```
353
354
### Custom Generic View with Filtering
355
356
```python
357
from rest_framework.generics import ListAPIView
358
from rest_framework.filters import SearchFilter, OrderingFilter
359
from django_filters.rest_framework import DjangoFilterBackend
360
361
class BookListView(ListAPIView):
362
queryset = Book.objects.all()
363
serializer_class = BookSerializer
364
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
365
filterset_fields = ['genre', 'publication_year']
366
search_fields = ['title', 'author__name']
367
ordering_fields = ['title', 'publication_date']
368
ordering = ['-publication_date']
369
370
def get_queryset(self):
371
# Custom queryset filtering
372
queryset = super().get_queryset()
373
author = self.request.query_params.get('author')
374
if author:
375
queryset = queryset.filter(author__name__icontains=author)
376
return queryset
377
```
378
379
### Using Mixins to Build Custom Views
380
381
```python
382
from rest_framework.mixins import ListModelMixin, CreateModelMixin
383
from rest_framework.generics import GenericAPIView
384
385
class CustomBookView(ListModelMixin, CreateModelMixin, GenericAPIView):
386
queryset = Book.objects.all()
387
serializer_class = BookSerializer
388
389
def get(self, request, *args, **kwargs):
390
return self.list(request, *args, **kwargs)
391
392
def post(self, request, *args, **kwargs):
393
return self.create(request, *args, **kwargs)
394
395
def perform_create(self, serializer):
396
# Custom creation logic
397
serializer.save(created_by=self.request.user)
398
```
399
400
## Utility Functions
401
402
```python { .api }
403
def get_object_or_404(queryset, *filter_args, **filter_kwargs):
404
"""
405
Get object from queryset or raise 404 error.
406
407
Args:
408
queryset: QuerySet to search
409
*filter_args: Filter arguments
410
**filter_kwargs: Filter keyword arguments
411
412
Returns:
413
Model instance
414
415
Raises:
416
Http404: If object not found
417
"""
418
```