django-patterns/SKILL.md
Django architecture patterns, REST API design with DRF, ORM best practices, caching, signals, middleware, and production-grade Django apps.
npx skillsauth add lidge-jun/cli-jaw-skills django-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Production-grade Django architecture patterns for scalable, maintainable applications.
myproject/
├── config/
│ ├── __init__.py
│ ├── settings/
│ │ ├── __init__.py
│ │ ├── base.py # Base settings
│ │ ├── development.py # Dev settings
│ │ ├── production.py # Production settings
│ │ └── test.py # Test settings
│ ├── urls.py
│ ├── wsgi.py
│ └── asgi.py
├── manage.py
└── apps/
├── __init__.py
├── users/
│ ├── __init__.py
│ ├── models.py
│ ├── views.py
│ ├── serializers.py
│ ├── urls.py
│ ├── permissions.py
│ ├── filters.py
│ ├── services.py
│ └── tests/
└── products/
└── ...
Split settings across base.py, development.py, production.py, and test.py. See references/code-examples.md § Split Settings for full configuration.
AbstractUser for custom user models with email-based authMeta with db_table, ordering, indexes, constraintsDecimalField for money, PositiveIntegerField for countssave() for auto-generated fields (e.g., slug from name)class Product(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
price = models.DecimalField(max_digits=10, decimal_places=2,
validators=[MinValueValidator(0)])
stock = models.PositiveIntegerField(default=0)
is_active = models.BooleanField(default=True)
category = models.ForeignKey('Category', on_delete=models.CASCADE,
related_name='products')
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created_at']
indexes = [
models.Index(fields=['slug']),
models.Index(fields=['category', 'is_active']),
]
Chain reusable query methods via a custom QuerySet.as_manager():
class ProductQuerySet(models.QuerySet):
def active(self):
return self.filter(is_active=True)
def with_category(self):
return self.select_related('category')
def in_stock(self):
return self.filter(stock__gt=0)
# Usage: Product.objects.active().with_category().in_stock()
See references/code-examples.md § Model Design for full models, QuerySet, and Manager examples.
SerializerMethodField for computed fieldssource='related.field' for nested attribute accessclass ProductSerializer(serializers.ModelSerializer):
category_name = serializers.CharField(source='category.name', read_only=True)
class Meta:
model = Product
fields = ['id', 'name', 'slug', 'price', 'category_name', 'created_at']
read_only_fields = ['id', 'slug', 'created_at']
def validate_price(self, value):
if value < 0:
raise serializers.ValidationError("Price cannot be negative.")
return value
get_serializer_class() for action-specific serializersperform_create() to inject request context (e.g., created_by)@action for custom endpoints beyond CRUDfilter_backends, search_fields, ordering_fieldsclass ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.select_related('category')
permission_classes = [IsAuthenticated, IsOwnerOrReadOnly]
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
search_fields = ['name', 'description']
def get_serializer_class(self):
if self.action == 'create':
return ProductCreateSerializer
return ProductSerializer
def perform_create(self, serializer):
serializer.save(created_by=self.request.user)
See references/code-examples.md § DRF Serializers and § DRF ViewSets for complete implementations.
Encapsulate business logic in service classes, keeping views thin. Use @transaction.atomic for multi-step operations.
See references/code-examples.md § Service Layer for OrderService example.
| Level | Approach | Duration |
|-------|----------|----------|
| View | @cache_page(timeout) decorator | Minutes |
| Template | {% cache ttl key %} fragment tag | Minutes |
| Low-level | cache.get() / cache.set() | Minutes–Hours |
| QuerySet | Cache list(queryset) results | Minutes–Hours |
See references/code-examples.md § Caching for examples of each level.
Use post_save / pre_save signals for cross-cutting concerns (e.g., auto-creating profiles). Register in AppConfig.ready().
See references/code-examples.md § Signals for implementation.
Use middleware for request/response processing (logging, user tracking, timing). Extend MiddlewareMixin with process_request / process_response.
See references/code-examples.md § Middleware for examples.
# Avoid: N+1 queries (separate query per product)
for product in Product.objects.all():
print(product.category.name)
# Prefer: single query with select_related (FK)
for product in Product.objects.select_related('category').all():
print(product.category.name)
# Prefer: prefetch_related for M2M
products = Product.objects.prefetch_related('tags').all()
Add indexes in Meta.indexes for columns used in WHERE, ORDER BY, and frequent JOINs. Use composite indexes for multi-column filtering.
Use bulk_create() and bulk_update() for batch data operations. See references/code-examples.md § Bulk Operations.
| Pattern | Description | |---------|-------------| | Split settings | Separate dev/prod/test settings | | Custom QuerySet | Reusable query methods | | Service Layer | Business logic separation | | ViewSet | REST API endpoints | | Serializer validation | Request/response transformation | | select_related | Foreign key optimization | | prefetch_related | Many-to-many optimization | | Cache first | Cache expensive operations | | Signals | Event-driven actions | | Middleware | Request/response processing |
For production applications, structure and organization matter more than concise code. Build for maintainability.
Current: Django 6.0.6 (June 2026). Django 6.1 alpha released May 2026.
tools
Use only on the Codex CLI for native image generation or image editing without an API key. Save final PNG files under ~/.cli-jaw/uploads, report web-ready absolute-path markdown, and send to Telegram or Discord only when explicitly requested.
tools
Ranked repository structure map via `cli-jaw map`. Use for codebase overview, structure map, symbol overview, unfamiliar codebase exploration, architecture orientation. Triggers: repo map, structure map, codebase overview, 와꾸, project structure, unfamiliar code.
tools
cli-jaw Design workspace: create, preview, run, and export design pages from the right sidebar. Covers panel UX, direct-write workflow, artifact lifecycle, wireframe generation, design system, and Open Design adapter.
development
MUST USE for infrastructure and delivery work — container builds, deploy pipelines, Kubernetes, Infrastructure as Code, SRE foundations, edge/serverless, ML infrastructure. Triggers: Dockerfile, K8s manifests, CI/CD pipeline, Terraform/IaC, release/deploy, devops/infra/deploy or release_cd task_tags.