Django REST framework
raw JSON → 3.15.1 verified Tue May 12 auth: no python install: stale
Django REST framework (DRF) is a powerful and flexible toolkit for building Web APIs in Django. It provides a robust set of tools for serialization, authentication, permissions, throttling, and viewsets, enabling rapid development of RESTful services. It is an actively maintained project with a steady release cadence, typically receiving several minor updates per year.
pip install djangorestframework Common errors
error AttributeError: 'Manager' object has no attribute 'all' ↓
cause Attempting to assign a Django model class directly to `queryset` (e.g., `queryset = MyModel`) instead of an actual QuerySet (e.g., `queryset = MyModel.objects.all()`).
fix
Change
queryset = MyModel to queryset = MyModel.objects.all() in your APIView, GenericAPIView, or ViewSet. error ImproperlyConfigured: Could not resolve URL for 'rest_framework:login' ↓
cause The `rest_framework.urls` are not included in your project's `urls.py` or are included with an incorrect namespace, preventing the browsable API login/logout views from being found.
fix
Add
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')) to your project's urls.py. error TypeError: Object of type <ModelName> is not JSON serializable ↓
cause An API view is attempting to return a raw Django model instance (or QuerySet of instances) directly in an `HttpResponse` or `Response` object without first converting it into a serializable format using a DRF Serializer.
fix
Ensure all Django model instances or QuerySets returned from API views are passed through a
Serializer or ModelSerializer instance and its .data property is used (e.g., return Response(MyModelSerializer(instance).data)). error AssertionError: You must set either `.queryset` or `.get_queryset()` in `ListView`. ↓
cause This error (or a similar one for `ViewSet`) occurs when a `GenericAPIView` or `ViewSet` subclass is used without explicitly defining a `queryset` class attribute or implementing a `get_queryset()` method.
fix
Define
queryset = MyModel.objects.all() or implement def get_queryset(self): return MyModel.objects.filter(...) in your view class. error django.core.exceptions.ImproperlyConfigured: Requested setting REST_FRAMEWORK, but settings are not configured. ↓
cause Django REST framework is not added to the `INSTALLED_APPS` list in your Django project's `settings.py`, so DRF cannot load its configuration.
fix
Add
'rest_framework' to your INSTALLED_APPS list in settings.py. Warnings
breaking When migrating from DRF 2.x to 3.x, `APIView` and `GenericAPIView` subclasses (including `ViewSet`s) no longer use `model = MyModel`. Instead, you must define `queryset = MyModel.objects.all()`. ↓
fix Change `model = MyModel` to `queryset = MyModel.objects.all()` in your views and viewsets.
breaking All Django REST framework settings moved from global variables in `settings.py` (e.g., `DEFAULT_AUTHENTICATION_CLASSES`) into a single `REST_FRAMEWORK` dictionary. ↓
fix Migrate your DRF settings into a `REST_FRAMEWORK = { ... }` dictionary in your Django `settings.py`. For example, `DEFAULT_AUTHENTICATION_CLASSES = [...]` becomes `REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': [...]}`.
gotcha When calling `serializer.is_valid()`, it's crucial to either check `serializer.errors` for validation failures or pass `raise_exception=True` to automatically raise a `ValidationError` with details. Neglecting this can lead to silent validation failures. ↓
fix Always use `serializer.is_valid(raise_exception=True)` or explicitly check `if not serializer.is_valid(): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)`.
deprecated Passing `authentication_classes` or `permission_classes` as arguments to `APIView.as_view()` is deprecated. These should be defined as class attributes on the `APIView` subclass. ↓
fix Move `authentication_classes = [...]` and `permission_classes = [...]` from the `as_view()` call to class attributes within your `APIView` or `ViewSet` classes.
gotcha For nested writable serializers, DRF does not automatically handle the creation or updating of nested objects. You must explicitly override the `create()` and/or `update()` methods in the parent serializer to handle nested data. ↓
fix Implement custom `create()` and `update()` methods in your serializer to explicitly save or update nested serializer instances. Refer to DRF's 'Writable nested serializers' documentation.
Install compatibility stale last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.68s 70.5M
3.10 alpine (musl) - - - -
3.10 slim (glibc) wheel 3.5s 0.54s 71M
3.10 slim (glibc) - - - -
3.11 alpine (musl) wheel - 0.86s 75.2M
3.11 alpine (musl) - - - -
3.11 slim (glibc) wheel 3.4s 0.75s 76M
3.11 slim (glibc) - - - -
3.12 alpine (musl) wheel - 0.99s 66.6M
3.12 alpine (musl) - - - -
3.12 slim (glibc) wheel 3.5s 0.95s 67M
3.12 slim (glibc) - - - -
3.13 alpine (musl) wheel - 1.04s 66.5M
3.13 alpine (musl) - - - -
3.13 slim (glibc) wheel 3.5s 0.98s 67M
3.13 slim (glibc) - - - -
3.9 alpine (musl) wheel - 0.64s 69.2M
3.9 alpine (musl) - - - -
3.9 slim (glibc) wheel 4.0s 0.56s 70M
3.9 slim (glibc) - - - -
Imports
- serializers
from rest_framework import serializers - views
from rest_framework import views - viewsets
from rest_framework import viewsets - permissions
from rest_framework import permissions - routers
from rest_framework import routers - Response wrong
from rest_framework import Responsecorrectfrom rest_framework.response import Response - APIView wrong
from rest_framework import APIViewcorrectfrom rest_framework.views import APIView - ModelSerializer wrong
from rest_framework import ModelSerializercorrectfrom rest_framework.serializers import ModelSerializer
Quickstart last tested: 2026-04-24
from rest_framework import serializers
# 1. Define a serializer for an item
class ItemSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(max_length=200)
description = serializers.CharField(allow_blank=True)
price = serializers.DecimalField(max_digits=10, decimal_places=2)
# Mock an object for demonstration (in a real Django app, this would be a model instance)
class MockItem:
def __init__(self, id, name, description, price):
self.id = id
self.name = name
self.description = description
self.price = price
def __repr__(self):
return f"MockItem(id={self.id}, name='{self.name}')"
# 2. Example data for creation
item_data = {'name': 'New Gadget', 'description': 'A very useful device', 'price': 99.99}
# 3. Deserialize (validate and prepare for creation/update)
create_serializer = ItemSerializer(data=item_data)
if create_serializer.is_valid(raise_exception=True):
print("\n--- Creation (Deserialization) ---")
print("Validated data for creation:", create_serializer.validated_data)
# In a real app: item = Item.objects.create(**create_serializer.validated_data)
# For demo: simulate saving
new_item = MockItem(id=1, **create_serializer.validated_data)
print("Simulated new item:", new_item)
# 4. Example existing object (for retrieval or update)
existing_item = MockItem(id=2, name='Old Widget', description='Not so useful now', price=25.00)
# 5. Serialize an existing object (for output)
output_serializer = ItemSerializer(existing_item)
print("\n--- Retrieval (Serialization) ---")
print("Serialized data from existing item:", output_serializer.data)
# 6. Example data for update
update_data = {'description': 'Still useful, with new features', 'price': 30.00}
# 7. Deserialize for update
update_serializer = ItemSerializer(existing_item, data=update_data, partial=True)
if update_serializer.is_valid(raise_exception=True):
print("\n--- Update (Partial Deserialization) ---")
print("Validated data for update:", update_serializer.validated_data)
# In a real app: for attr, value in update_serializer.validated_data.items(): setattr(existing_item, attr, value); existing_item.save()
# For demo: simulate update
for attr, value in update_serializer.validated_data.items():
setattr(existing_item, attr, value)
print("Simulated updated item:", existing_item)