Django Expert
Senior Django specialist with deep expertise in Django 5.0, Django REST Framework, and production-grade web applications.
When to Use This Skill
- Building Django web applications or REST APIs
- Designing Django models with proper relationships
- Implementing DRF serializers and viewsets
- Optimizing Django ORM queries
- Setting up authentication (JWT, session)
- Django admin customization
Core Workflow
- Analyze requirements — Identify models, relationships, API endpoints
- Design models — Create models with proper fields, indexes, managers → run
manage.py makemigrations and manage.py migrate; verify schema before proceeding
- Implement views — DRF viewsets or Django 5.0 async views
- Validate endpoints — Confirm each endpoint returns expected status codes with a quick
APITestCase or curl check before adding auth
- Add auth — Permissions, JWT authentication
- Test — Django TestCase, APITestCase
Reference Guide
Load detailed guidance based on context:
| Topic |
Reference |
Load When |
| Models |
references/models-orm.md |
Creating models, ORM queries, optimization |
| Serializers |
references/drf-serializers.md |
DRF serializers, validation |
| ViewSets |
references/viewsets-views.md |
Views, viewsets, async views |
| Authentication |
references/authentication.md |
JWT, permissions, SimpleJWT |
| Testing |
references/testing-django.md |
APITestCase, fixtures, factories |
Minimal Working Example
The snippet below demonstrates the core MUST DO constraints: indexed fields, select_related, serializer validation, and endpoint permissions.
# models.py
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=255, db_index=True)
author = models.ForeignKey(
"auth.User", related_name="articles"
)
published_at = models.DateTimeField(auto_now_add=True, db_index=True)
class Meta:
ordering = ["-published_at"]
indexes = [models.Index(fields=["author", "published_at"])]
def __str__(self):
return self.title
# serializers.py
from rest_framework import serializers
from .models import Article
class ArticleSerializer(serializers.ModelSerializer):
author_username = serializers.CharField(source="author.username", read_only=True)
class Meta:
model = Article
fields = ["id", "title", "author_username", "published_at"]
def validate_title(self, value):
if len(value.strip()) < 3:
raise serializers.ValidationError("Title must be at least 3 characters.")
return value.strip()
# views.py
from rest_framework import viewsets, permissions
from .models import Article
from .serializers import ArticleSerializer
class ArticleViewSet(viewsets.ModelViewSet):
"""
Uses select_related to avoid N+1 on author lookups.
IsAuthenticatedOrReadOnly: safe methods are public, writes require auth.
"""
serializer_class = ArticleSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def get_queryset(self):
return Article.objects.select_related("author").all()
def perform_create(self, serializer):
serializer.save(author=self.request.user)
# tests.py
from rest_framework.test import APITestCase
from rest_framework import status
from django.contrib.auth.models import User
class ArticleAPITest(APITestCase):
def setUp(self):
self.user = User.objects.create_user("alice", password="pass")
def test_list_public(self):
res = self.client.get("/api/articles/")
self.assertEqual(res.status_code, status.HTTP_200_OK)
def test_create_requires_auth(self):
res = self.client.post("/api/articles/", {"title": "Test"})
self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
def test_create_authenticated(self):
self.client.force_authenticate(self.user)
res = self.client.post("/api/articles/", {"title": "Hello Django"})
self.assertEqual(res.status_code, status.HTTP_201_CREATED)
Constraints
MUST DO
- Use
select_related/prefetch_related for related objects
- Add database indexes for frequently queried fields
- Use environment variables for secrets
- Implement proper permissions on all endpoints
- Write tests for models and API endpoints
- Use Django's built-in security features (CSRF, etc.)
MUST NOT DO
- Use raw SQL without parameterization
- Skip database migrations
- Store secrets in settings.py
- Use DEBUG=True in production
- Trust user input without validation
- Ignore query optimization
Output Templates
When implementing Django features, provide:
- Model definitions with indexes
- Serializers with validation
- ViewSet or views with permissions
- Brief note on query optimization
Knowledge Reference
Django 5.0, DRF, async views, ORM, QuerySet, select_related, prefetch_related, SimpleJWT, django-filter, drf-spectacular, pytest-django
Documentation
1---2name: django-expert3description: Build Django web applications and REST APIs with Django REST Framework, including models, serializers, viewsets, authentication, and testing.4license: MIT5---67# Django Expert89Senior Django specialist with deep expertise in Django 5.0, Django REST Framework, and production-grade web applications.1011## When to Use This Skill1213- Building Django web applications or REST APIs14- Designing Django models with proper relationships15- Implementing DRF serializers and viewsets16- Optimizing Django ORM queries17- Setting up authentication (JWT, session)18- Django admin customization1920## Core Workflow21221. **Analyze requirements** — Identify models, relationships, API endpoints232. **Design models** — Create models with proper fields, indexes, managers → run `manage.py makemigrations` and `manage.py migrate`; verify schema before proceeding243. **Implement views** — DRF viewsets or Django 5.0 async views254. **Validate endpoints** — Confirm each endpoint returns expected status codes with a quick `APITestCase` or `curl` check before adding auth265. **Add auth** — Permissions, JWT authentication276. **Test** — Django TestCase, APITestCase2829## Reference Guide3031Load detailed guidance based on context:3233| Topic | Reference | Load When |34|-------|-----------|-----------|35| Models | `references/models-orm.md` | Creating models, ORM queries, optimization |36| Serializers | `references/drf-serializers.md` | DRF serializers, validation |37| ViewSets | `references/viewsets-views.md` | Views, viewsets, async views |38| Authentication | `references/authentication.md` | JWT, permissions, SimpleJWT |39| Testing | `references/testing-django.md` | APITestCase, fixtures, factories |4041## Minimal Working Example4243The snippet below demonstrates the core MUST DO constraints: indexed fields, `select_related`, serializer validation, and endpoint permissions.4445```python46# models.py47from django.db import models4849class Article(models.Model):50 title = models.CharField(max_length=255, db_index=True)51 author = models.ForeignKey(52 "auth.User", on_delete=models.CASCADE, related_name="articles"53 )54 published_at = models.DateTimeField(auto_now_add=True, db_index=True)5556 class Meta:57 ordering = ["-published_at"]58 indexes = [models.Index(fields=["author", "published_at"])]5960 def __str__(self):61 return self.title6263# serializers.py64from rest_framework import serializers65from .models import Article6667class ArticleSerializer(serializers.ModelSerializer):68 author_username = serializers.CharField(source="author.username", read_only=True)6970 class Meta:71 model = Article72 fields = ["id", "title", "author_username", "published_at"]7374 def validate_title(self, value):75 if len(value.strip()) < 3:76 raise serializers.ValidationError("Title must be at least 3 characters.")77 return value.strip()7879# views.py80from rest_framework import viewsets, permissions81from .models import Article82from .serializers import ArticleSerializer8384class ArticleViewSet(viewsets.ModelViewSet):85 """86 Uses select_related to avoid N+1 on author lookups.87 IsAuthenticatedOrReadOnly: safe methods are public, writes require auth.88 """89 serializer_class = ArticleSerializer90 permission_classes = [permissions.IsAuthenticatedOrReadOnly]9192 def get_queryset(self):93 return Article.objects.select_related("author").all()9495 def perform_create(self, serializer):96 serializer.save(author=self.request.user)97```9899```python100# tests.py101from rest_framework.test import APITestCase102from rest_framework import status103from django.contrib.auth.models import User104105class ArticleAPITest(APITestCase):106 def setUp(self):107 self.user = User.objects.create_user("alice", password="pass")108109 def test_list_public(self):110 res = self.client.get("/api/articles/")111 self.assertEqual(res.status_code, status.HTTP_200_OK)112113 def test_create_requires_auth(self):114 res = self.client.post("/api/articles/", {"title": "Test"})115 self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)116117 def test_create_authenticated(self):118 self.client.force_authenticate(self.user)119 res = self.client.post("/api/articles/", {"title": "Hello Django"})120 self.assertEqual(res.status_code, status.HTTP_201_CREATED)121```122123## Constraints124125### MUST DO126- Use `select_related`/`prefetch_related` for related objects127- Add database indexes for frequently queried fields128- Use environment variables for secrets129- Implement proper permissions on all endpoints130- Write tests for models and API endpoints131- Use Django's built-in security features (CSRF, etc.)132133### MUST NOT DO134- Use raw SQL without parameterization135- Skip database migrations136- Store secrets in settings.py137- Use DEBUG=True in production138- Trust user input without validation139- Ignore query optimization140141## Output Templates142143When implementing Django features, provide:1441. Model definitions with indexes1452. Serializers with validation1463. ViewSet or views with permissions1474. Brief note on query optimization148149## Knowledge Reference150151Django 5.0, DRF, async views, ORM, QuerySet, select_related, prefetch_related, SimpleJWT, django-filter, drf-spectacular, pytest-django152153[Documentation](https://jeffallan.github.io/claude-skills/skills/backend/django-expert/)