Install & Compatibility
Where this runs
tested against v3.18.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.960s · 70.5MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 3.7s · import 0.832s · 71MB
70MB installed
● package 70MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
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
✓ from rest_framework.response import Response
✗ from rest_framework import Response
Response is part of the `response` module, not directly from the top-level `rest_framework` package.
APIView
✓ from rest_framework.views import APIView
✗ from rest_framework import APIView
APIView is part of the `views` module, not directly from the top-level `rest_framework` package.
ModelSerializer
✓ from rest_framework.serializers import ModelSerializer
✗ from rest_framework import ModelSerializer
ModelSerializer is part of the `serializers` module, not directly from the top-level `rest_framework` package.
This quickstart demonstrates the core functionality of Django REST framework serializers: how to define them, validate incoming data (deserialization), and convert Python objects into API-ready data (serialization). While DRF is typically used within a full Django project to build API views for models, this example focuses on the serializer's standalone usage for clarity and runnability.
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)
Debug
Known issues
breakingWhen 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()`.fixChange `model = MyModel` to `queryset = MyModel.objects.all()` in your views and viewsets.
affects: <3.0 to >=3.0
breakingAll Django REST framework settings moved from global variables in `settings.py` (e.g., `DEFAULT_AUTHENTICATION_CLASSES`) into a single `REST_FRAMEWORK` dictionary.fixMigrate your DRF settings into a `REST_FRAMEWORK = { ... }` dictionary in your Django `settings.py`. For example, `DEFAULT_AUTHENTICATION_CLASSES = [...]` becomes `REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': [...]}`. affects: <3.0 to >=3.0
gotchaWhen 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.fixAlways 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)`.
affects: >=3.0
deprecatedPassing `authentication_classes` or `permission_classes` as arguments to `APIView.as_view()` is deprecated. These should be defined as class attributes on the `APIView` subclass.fixMove `authentication_classes = [...]` and `permission_classes = [...]` from the `as_view()` call to class attributes within your `APIView` or `ViewSet` classes.
affects: >=3.10, removed in 3.11
gotchaFor 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.fixImplement custom `create()` and `update()` methods in your serializer to explicitly save or update nested serializer instances. Refer to DRF's 'Writable nested serializers' documentation.
affects: All versions
Errors
Common errors & fixes
AttributeError: 'Manager' object has no attribute 'all'
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()`).
fixChange `queryset = MyModel` to `queryset = MyModel.objects.all()` in your `APIView`, `GenericAPIView`, or `ViewSet`.
ImproperlyConfigured: Could not resolve URL for 'rest_framework:login'
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.
fixAdd `path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))` to your project's `urls.py`. TypeError: Object of type <ModelName> is not JSON serializable
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.
fixEnsure 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)`).
AssertionError: You must set either `.queryset` or `.get_queryset()` in `ListView`.
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.
fixDefine `queryset = MyModel.objects.all()` or implement `def get_queryset(self): return MyModel.objects.filter(...)` in your view class.
django.core.exceptions.ImproperlyConfigured: Requested setting REST_FRAMEWORK, but settings are not configured.
Django REST framework is not added to the `INSTALLED_APPS` list in your Django project's `settings.py`, so DRF cannot load its configuration.
fixAdd `'rest_framework'` to your `INSTALLED_APPS` list in `settings.py`.
Upgrade
Version history
3.18.0latest on PyPI · released Aug 7, 2026
Audit
Dependencies
DjangorequiredDRF is built on top of Django and requires a Django project to function.
pytzoptionalOften needed for timezone support in Django projects, though newer Django versions use `zoneinfo` by default.
markdownoptionalRequired for the browsable API feature to display Markdown in documentation.
django-filteroptionalProvides powerful filtering backend for API views.