You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**Django REST Framework API Mixins** - A collection of powerful, reusable mixins for Django REST Framework ViewSets and APIViews to simplify common API development patterns. Perfect for building REST APIs with Django.
10
12
11
13
**📦 Available on PyPI**: [https://pypi.org/project/django-api-mixins/](https://pypi.org/project/django-api-mixins/)
Automatically sets `filterset_fields` from a model that uses `ModelMixin` (or any model with a `get_filter_fields()` class method). Works with APIView, GenericAPIView, and ViewSets.
137
125
126
+
**You must set `model` on the view** so the mixin can resolve filter fields (e.g. `model = Unit`). For ViewSets, use the same model as your queryset.
127
+
128
+
#### APIView: default `get()` — list and detail in one view
129
+
130
+
When used with **APIView**, the mixin provides a default `get(request, *args, **kwargs)` so a single view can serve both list and detail:
131
+
132
+
-**Detail**: If the URL includes the lookup key (default `pk`) in `kwargs` — e.g. `GET /units/5/` — the mixin returns the single object (serialized) or 404 if not found. Filtering still applies to the base queryset before fetching the object.
133
+
-**List**: If the lookup key is not in `kwargs` — e.g. `GET /units/` — the mixin returns the filtered list (no pagination). Query params are applied via `django-filter` and `filterset_fields`.
134
+
135
+
You must set `serializer_class` on the view for the default `get()` to work. Optionally set `detail_not_found_message` (default `"Not found"`), `lookup_url_kwarg` (default `"pk"`), and `lookup_field` (default `"pk"`).
136
+
137
+
**Example: use the default `get()` (no override)**
138
+
138
139
```python
139
-
from rest_framework importviewsets
140
+
from rest_framework.viewsimportAPIView
140
141
from django_filters.rest_framework import DjangoFilterBackend
141
142
from django_api_mixins import ModelFilterFieldsMixin
142
143
143
-
# ViewSet / GenericAPIView: filter fields come from queryset.model
# filterset_fields auto-set from Unit.get_filter_fields()
148
+
# Optional: detail_not_found_message = "Unit not found"
149
+
150
+
# Optional: override to customize queryset; otherwise mixin uses model.objects.all()
151
+
defget_queryset(self):
152
+
return Unit.objects.all()
153
+
154
+
# Do NOT override get() — mixin handles list and detail
155
+
```
156
+
157
+
-`GET /units/` → filtered list (e.g. `?name=foo` applied).
158
+
-`GET /units/42/` → single unit with id 42, or 404.
159
+
160
+
#### APIView: override `get()` for custom behavior
161
+
162
+
You can override `get()` and still reuse the mixin's helpers:
163
+
164
+
-**`get_filtered_queryset()`** — base queryset with all filter backends applied.
165
+
-**`get_object(pk=None)`** — single instance by pk (from URL kwargs if `pk` omitted); raises `Http404` if not found.
166
+
-**`get_detail_data(request, *args, **kwargs)`** — returns `(body, status_code)` for the detail response (serialized object or 404 body).
167
+
-**`get_list_data(request, *args, queryset=None, **kwargs)`** — returns `(data, status_code)` for the list response; if `queryset` is passed (e.g. a paginated page), that is used instead of the full filtered queryset.
149
168
150
-
# APIView: set model so the mixin can resolve filter fields
169
+
**Example: add pagination for list only; detail unchanged**
170
+
171
+
```python
151
172
from rest_framework.views import APIView
173
+
from rest_framework.response import Response
174
+
from rest_framework.pagination import PageNumberPagination
175
+
from django_filters.rest_framework import DjangoFilterBackend
176
+
from django_api_mixins import ModelFilterFieldsMixin
**Example: list + detail without pagination (with Swagger/OpenAPI filter params)**
234
+
235
+
If you want list and detail in one APIView **without pagination** and you want filter parameters to appear in Swagger/OpenAPI docs, combine `OpenAPIFilterParametersMixin` with `ModelFilterFieldsMixin` and override `get()`:
236
+
237
+
```python
238
+
from rest_framework.views import APIView
239
+
from rest_framework.response import Response
240
+
from rest_framework import status
241
+
from django_filters.rest_framework import DjangoFilterBackend
242
+
from django_api_mixins import OpenAPIFilterParametersMixin, ModelFilterFieldsMixin
243
+
244
+
# Optional: add to Swagger UI tags (requires drf-spectacular)
filterset_model = Unit # use Unit.get_filter_fields() instead of SomeProxy
168
289
filter_backends = [DjangoFilterBackend]
169
290
```
170
291
171
-
**Note**: If `django-filter` is not installed, you'll get a clear error message with installation instructions when you try to use this mixin.
292
+
**Note**: If `django-filter` is not installed, you'll get a clear error message with installation instructions when you try to use this mixin. You can still set `filterset_fields` explicitly on the view to override the auto-generated fields.
172
293
173
294
### OpenAPIFilterParametersMixin
174
295
@@ -203,6 +324,31 @@ class UnitListAPIView(ModelFilterFieldsMixin, APIView):
203
324
204
325
**Note**: If `django-filter` or `drf-spectacular` is not installed, you'll get a clear error message with installation instructions when you try to use this mixin.
205
326
327
+
### APIMixin
328
+
329
+
Use different serializers for different actions (create, update, list, retrieve):
description = "Django REST Framework mixins for ViewSets and APIViews - APIMixin, ModelMixin, RelationshipFilterMixin, RoleBasedFilterMixin. Simplify Django API development with reusable mixins."
0 commit comments