Django 6 + Django REST Framework model API with pytest-django: working versions (tested 2026-10-15)
A DRF ModelViewSet with a serializer, router and token-free permissions, tested with pytest-django and APIClient on in-memory SQLite.
passed3 passed · 0 failed2026-10-15 13:06 UTC- Status
- passed
- Last passed
- 2026-10-15 13:06 UTC
- Tests
- 3 / 3
- Language
- Python
- Runtime
- Python 3.13.16
uv venv -q .venv && uv pip install -q --python .venv/bin/python -r requirements.txt .venv/bin/python -m pytest -q
Python 3.13.16 linux 6.17.0-1022-azure x64 runner: github-actions 38738874208
The code
Exactly the files that passed. Your agent can pull them with get_recipe("django-drf-api") (install), or see them on GitHub.
django==6.1.2 djangorestframework==3.18.3 pytest-django==4.14.0 pytest==9.1.1
SECRET_KEY = "test-only"
DEBUG = True
ALLOWED_HOSTS = ["*"]
INSTALLED_APPS = ["django.contrib.contenttypes", "django.contrib.auth", "rest_framework", "books"]
DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}}
ROOT_URLCONF = "urls"
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
USE_TZ = True
REST_FRAMEWORK = {"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.IsAuthenticatedOrReadOnly"]}
from rest_framework.routers import DefaultRouter
from books.views import BookViewSet
router = DefaultRouter()
router.register("books", BookViewSet)
urlpatterns = router.urls
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200)
isbn = models.CharField(max_length=13, unique=True)
published = models.DateField(null=True, blank=True)
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ["id", "title", "isbn", "published"]
def validate_isbn(self, value):
if not value.isdigit() or len(value) not in (10, 13):
raise serializers.ValidationError("ISBN must be 10 or 13 digits")
return value
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.order_by("id")
serializer_class = BookSerializer
import pytest
from django.contrib.auth.models import User
from rest_framework.test import APIClient
pytestmark = pytest.mark.django_db
@pytest.fixture
def auth_client():
c = APIClient()
c.force_authenticate(User.objects.create_user("ada"))
return c
def test_create_and_list(auth_client):
r = auth_client.post("/books/", {"title": "SICP", "isbn": "9780262510875"}, format="json")
assert r.status_code == 201
assert APIClient().get("/books/").json()[0]["title"] == "SICP"
def test_validation(auth_client):
r = auth_client.post("/books/", {"title": "X", "isbn": "abc"}, format="json")
assert r.status_code == 400 and "isbn" in r.json()
def test_anonymous_cannot_write():
assert APIClient().post("/books/", {"title": "X", "isbn": "1234567890"}, format="json").status_code in (401, 403)
[pytest] pythonpath = . DJANGO_SETTINGS_MODULE = settings
Connect to ProvenPin
Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp
{ "mcpServers": { "provenpin": { "url": "https://mcp.provenpin.com/mcp" } } }{ "servers": { "provenpin": { "type": "http", "url": "https://mcp.provenpin.com/mcp" } } }{ "mcpServers": { "provenpin": { "serverUrl": "https://mcp.provenpin.com/mcp" } } }{ "mcpServers": { "provenpin": { "type": "streamableHttp", "url": "https://mcp.provenpin.com/mcp" } } }Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.
Related stacks
Django REST Framework JWT auth with simplejwt, tested offline
Obtain and refresh JWT pairs with simplejwt, add custom claims, protect a DRF view, and test expired-token rejection on sqlite in-memory with pytest-django.
DRF ModelViewSet with django-filter range, exact and ordering filters
A ModelViewSet with a django-filter FilterSet for price ranges, exact name and ordering, plus page-number pagination, configured in code and tested offline with APIClient on in-memory SQLite.
Django models with factory_boy and pytest-django db fixtures
Django models built with factory_boy DjangoModelFactory (SubFactory, get_or_create, traits) and tested offline on in-memory SQLite with pytest-django database access rules and on_commit capture.
Django Ninja API with Schema models and pagination on sqlite
A typed Django Ninja CRUD API with Schema input and output models, page-number pagination and sqlite, tested offline with the ninja TestClient and pytest-django.
All Django recipesAll Django REST Framework recipesAll pytest-django recipes