ProvenPin Install

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 11:34 UTC
Status
passed
Last passed
2026-10-15 11:34 UTC
Tests
3 / 3
Language
Python
Runtime
Python 3.13.16
pinned versions4
django@6.1.2djangorestframework@3.18.3pytest-django@4.14.0pytest@9.1.1
run it
uv venv -q .venv && uv pip install -q --python .venv/bin/python -r requirements.txt
.venv/bin/python -m pytest -q
test environment
Python 3.13.16
linux 6.17.0-1022-azure
x64
runner: github-actions 38728226240

The code

Exactly the files that passed. Your agent can pull them with get_recipe("django-drf-api") (install), or see them on GitHub.

requirements.txt
django==6.1.2
djangorestframework==3.18.3
pytest-django==4.14.0
pytest==9.1.1
settings.py
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"]}
urls.py
from rest_framework.routers import DefaultRouter
from books.views import BookViewSet

router = DefaultRouter()
router.register("books", BookViewSet)
urlpatterns = router.urls
books/__init__.py
books/models.py
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)
books/serializers.py
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
books/views.py
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
tests/test_books.py
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.ini
[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.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.