PEP 484 type stubs for Django REST Framework enabling static type checking with comprehensive type definitions for all major DRF components
npx @tessl/cli install tessl/pypi-djangorestframework-stubs@3.16.0Django REST Framework Stubs provides comprehensive type definitions for Django REST Framework (DRF), enabling full type checking support for DRF applications without requiring access to the source code. This package includes PEP 484 type stubs for all major DRF components plus a mypy plugin for enhanced static analysis.
Package Name: djangorestframework-stubs
Version: 3.16.2
Language: Python
Purpose: PEP 484 type stubs for Django REST Framework
Python Support: 3.10+
Installation: pip install djangorestframework-stubs[compatible-mypy]
Install the package with mypy support:
pip install djangorestframework-stubs[compatible-mypy]Configure mypy in mypy.ini:
[mypy]
plugins = mypy_drf_plugin.mainfrom rest_framework import serializers, views, generics
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework import status
from django.contrib.auth.models import User
from myapp.models import Book
# Typed serializer with automatic field inference
class BookSerializer(serializers.ModelSerializer[Book]):
class Meta:
model = Book
fields = ['id', 'title', 'author', 'published_date']
# Typed API view with proper request/response types
class BookListCreateView(generics.ListCreateAPIView[Book]):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = [IsAuthenticated]
# Typed function-based view
@api_view(['GET', 'POST'])
def book_list(request) -> Response:
if request.method == 'GET':
books = Book.objects.all()
serializer = BookSerializer(books, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = BookSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)# Essential DRF components
from rest_framework import serializers
from rest_framework import views
from rest_framework import generics
from rest_framework import viewsets
from rest_framework import mixins
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework import status
from rest_framework import permissions
from rest_framework import authentication
from rest_framework.routers import DefaultRouter
from rest_framework import exceptionsThe package provides type stubs in the rest_framework-stubs/ directory that mirror the actual DRF package structure:
serializers.pyi, views.pyi, generics.pyi, viewsets.pyiauthentication.pyi, permissions.pyifields.pyi, relations.pyi, parsers.pyi, renderers.pyirouters.pyi, decorators.pyi, pagination.pyi, filters.pyiauthtoken/, schemas/, utils/The mypy_drf_plugin provides additional type checking capabilities:
# Plugin configuration in mypy.ini
[mypy]
plugins = mypy_drf_plugin.main
# Enhanced typing for serializers
class UserSerializer(serializers.ModelSerializer[User]):
class Meta:
model = User
fields = '__all__'
# Plugin automatically infers field types from model
# and provides enhanced validationComplete type definitions for all serializer types with generic support:
# Generic serializer with type parameters
class BaseSerializer(Field[_VT, _DT, _RP, _IN]):
partial: bool
many: bool
instance: _IN | None
def is_valid(*, raise_exception: bool = False) -> bool: ...
def save(**kwargs: Any) -> _IN: ...
def create(validated_data: Any) -> _IN: ...
def update(instance: _IN, validated_data: Any) -> _IN: ...
# Model serializer with model type binding
class ModelSerializer(Serializer[_MT]):
class Meta:
model: type[_MT]
fields: str | Sequence[str]
exclude: Sequence[str] | None→ Complete Serializer Documentation
Comprehensive typing for all view classes and mixins:
# Generic API view with model type support
class GenericAPIView(APIView, Generic[_MT]):
queryset: QuerySet[_MT] | Manager[_MT] | None
serializer_class: type[BaseSerializer[_MT]] | None
def get_object() -> _MT: ...
def get_serializer() -> BaseSerializer[_MT]: ...
# ViewSet with proper action typing
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet[_MT]): ...→ Complete Views & ViewSets Documentation
Type-safe authentication and permission classes:
# Base authentication interface
class BaseAuthentication:
def authenticate(request: Request) -> tuple[Any, Any] | None: ...
def authenticate_header(request: Request) -> str | None: ...
# Permission system with logical operators
class BasePermission:
def has_permission(request: Request, view: APIView) -> bool: ...
def has_object_permission(request: Request, view: APIView, obj: Any) -> bool: ...
# Permission composition
permission_classes = [IsAuthenticated & (IsOwner | IsAdmin)]→ Complete Authentication & Permissions Documentation
Typed request and response objects:
# Enhanced request object
class Request(HttpRequest):
data: dict[str, Any]
query_params: QueryDict
user: AbstractUser | AnonymousUser
auth: Any
# Typed response
class Response(SimpleTemplateResponse):
data: Any
status_code: int
exception: bool→ Complete Request & Response Documentation
Complete field type system with generic support:
# Generic field base class
class Field(Generic[_VT, _DT, _RP, _IN]):
required: bool
allow_null: bool
default: Any
# Specific field types
class CharField(Field[str, str, str, Any]): ...
class IntegerField(Field[int, int | str, int, Any]): ...
class DateTimeField(Field[datetime, datetime | str, str, Any]): ...
# Relational fields
class PrimaryKeyRelatedField(RelatedField[_MT, _MT, Any]): ...
class HyperlinkedRelatedField(RelatedField[_MT, str, Hyperlink]): ...→ Complete Fields & Relations Documentation
Type-safe router and URL pattern configuration:
# Router with viewset registration
class DefaultRouter(BaseRouter):
def register(prefix: str, viewset: type[ViewSetMixin], basename: str | None = None) -> None: ...
def get_urls() -> list[URLPattern]: ...
# Route configuration
class Route(NamedTuple):
url: str
mapping: dict[str, str]
name: str
detail: bool→ Complete Routing & URLs Documentation
Typed pagination and filtering systems:
# Pagination base class
class BasePagination:
def paginate_queryset(queryset: QuerySet[_MT], request: Request, view: APIView | None = None) -> list[_MT] | None: ...
def get_paginated_response(data: Any) -> Response: ...
# Filter backends
class BaseFilterBackend:
def filter_queryset(request: Request, queryset: QuerySet[_MT], view: APIView) -> QuerySet[_MT]: ...→ Complete Pagination & Filtering Documentation
Comprehensive exception types with proper error detail handling:
# Base API exception
class APIException(Exception):
status_code: int
default_detail: str | dict | list
default_code: str
detail: Any
def get_codes() -> dict | list | str: ...
def get_full_details() -> dict | list: ...
# Specific exception types
class ValidationError(APIException): ...
class NotFound(APIException): ...
class PermissionDenied(APIException): ...→ Complete Exception & Status Documentation
This type stub package enables:
The included mypy plugin (mypy_drf_plugin.main) provides:
Complete example showing type-safe DRF development:
from django.contrib.auth.models import User
from rest_framework import serializers, viewsets, permissions
from rest_framework.decorators import action
from rest_framework.response import Response
from myapp.models import Article
class ArticleSerializer(serializers.ModelSerializer[Article]):
author_name = serializers.CharField(source='author.username', read_only=True)
class Meta:
model = Article
fields = ['id', 'title', 'content', 'author', 'author_name', 'created_at']
read_only_fields = ['author', 'created_at']
def create(self, validated_data: dict) -> Article:
validated_data['author'] = self.context['request'].user
return super().create(validated_data)
class ArticleViewSet(viewsets.ModelViewSet[Article]):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
@action(detail=True, methods=['post'], permission_classes=[permissions.IsAuthenticated])
def favorite(self, request, pk: str | None = None) -> Response:
article = self.get_object()
# Type-safe operations with proper return type
article.favorites.add(request.user)
return Response({'status': 'favorite added'})This example demonstrates how the type stubs enable full type safety across serializers, views, permissions, and custom actions while maintaining DRF's flexibility and power.