internal/skills/content/django/SKILL.md
Django 5+ framework guardrails, patterns, and best practices for AI-assisted development. Use when working with Django projects, or when the user mentions Django. Provides ORM patterns, views, templates, DRF, admin, and security guidelines.
npx skillsauth add ar4mirez/samuel djangoInstall 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.
Applies to: Django 5+, Django REST Framework, Django Channels Language: Python 3.10+
Good fit:
Consider alternatives:
myproject/
├── manage.py
├── pyproject.toml
├── requirements/
│ ├── base.txt
│ ├── dev.txt
│ └── prod.txt
├── config/ # Project configuration
│ ├── __init__.py
│ ├── settings/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── dev.py
│ │ └── prod.py
│ ├── urls.py
│ ├── wsgi.py
│ └── asgi.py
├── apps/ # Django applications
│ ├── users/
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── models.py
│ │ ├── views.py
│ │ ├── urls.py
│ │ ├── forms.py
│ │ ├── serializers.py # If using DRF
│ │ ├── services.py # Business logic
│ │ └── tests/
│ │ ├── __init__.py
│ │ ├── test_models.py
│ │ ├── test_views.py
│ │ └── test_services.py
│ └── core/ # Shared utilities
│ ├── __init__.py
│ ├── models.py # Abstract base models
│ └── mixins.py
├── templates/
│ ├── base.html
│ └── components/
├── static/
│ ├── css/
│ └── js/
└── tests/
└── conftest.py
base.py, dev.py, prod.pyapps/ directorycore/ app for shared abstract models and utilitiesservices.py, not in viewstests/ directorySECRET_KEY -- use python-decouple or environment variablesbase.py (shared), dev.py (debug), prod.py (secure)AUTH_USER_MODEL before first migrationDEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"ALLOWED_HOSTS in production (never ["*"])__str__ on every modelclass Meta with db_table, ordering, and indexesTimeStampedModel, UUIDModel)TextChoices/IntegerChoices for status fields (not raw strings)related_name to all ForeignKey and OneToOneField relationshipson_delete explicitly: CASCADE, PROTECT, SET_NULL, SET_DEFAULTvalidators at model level for domain constraints# apps/core/models.py
from django.db import models
import uuid
class TimeStampedModel(models.Model):
"""Abstract base with created/updated timestamps."""
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class UUIDModel(models.Model):
"""Abstract base with UUID primary key."""
id = models.UUIDField(
primary_key=True, default=uuid.uuid4, editable=False
)
class Meta:
abstract = True
AbstractUser (not AbstractBaseUser unless you need full control)AUTH_USER_MODEL = "users.User" in settings# apps/users/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from apps.core.models import TimeStampedModel, UUIDModel
class User(AbstractUser, UUIDModel, TimeStampedModel):
email = models.EmailField(unique=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username"]
class Meta:
db_table = "users"
ordering = ["-created_at"]
indexes = [models.Index(fields=["email"])]
def __str__(self) -> str:
return self.email
ListView, DetailView, CreateView, UpdateView for CRUDLoginRequiredMixin for authenticated viewsget_queryset() to add filtering and select_related/prefetch_relatedform_valid() to inject the current userfrom django.views.generic import ListView
from django.db.models import Q
from .models import Product
class ProductListView(ListView):
model = Product
template_name = "products/list.html"
context_object_name = "products"
paginate_by = 20
def get_queryset(self):
qs = Product.objects.filter(
status=Product.Status.PUBLISHED
)
search = self.request.GET.get("q")
if search:
qs = qs.filter(
Q(name__icontains=search)
| Q(description__icontains=search)
)
return qs.select_related("category")
# config/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("api/", include("apps.api.urls")),
path("", include("apps.products.urls")),
]
include() for app-level URL namespacesapp_name in each app's urls.py for reverse resolutionselect_related() for ForeignKey/OneToOne (SQL JOIN)prefetch_related() for ManyToMany/reverse FK (separate query)only() or defer() to limit fields when not all columns neededModel.objects.all() without pagination or limitsF() expressions for database-level operationsQ() objects for complex lookups# BAD: N+1 queries
for product in Product.objects.all():
print(product.category.name) # Extra query per product
# GOOD: Single JOIN query
for product in Product.objects.select_related("category"):
print(product.category.name) # No extra queries
@transaction.atomic for multi-step writesselect_for_update() for optimistic lockingfrom django.db import transaction
@transaction.atomic
def transfer_stock(source_id, dest_id, qty):
source = Product.objects.select_for_update().get(id=source_id)
dest = Product.objects.select_for_update().get(id=dest_id)
source.stock -= qty
dest.stock += qty
source.save(update_fields=["stock"])
dest.save(update_fields=["stock"])
from django.contrib import admin
from .models import Product
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ["name", "category", "price", "status"]
list_filter = ["status", "category", "created_at"]
search_fields = ["name", "description"]
prepopulated_fields = {"slug": ("name",)}
readonly_fields = ["created_at", "updated_at"]
ordering = ["-created_at"]
fieldsets = (
(None, {"fields": ("name", "slug", "description")}),
("Pricing", {"fields": ("price", "stock")}),
("Classification", {"fields": ("category", "status")}),
("Timestamps", {
"fields": ("created_at", "updated_at"),
"classes": ("collapse",),
}),
)
@admin.register(Model)list_display for useful columns, list_filter for filteringprepopulated_fields for slug generationfieldsets for organized admin formsREST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.SessionAuthentication",
"rest_framework_simplejwt.authentication.JWTAuthentication",
],
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated",
],
"DEFAULT_PAGINATION_CLASS": (
"rest_framework.pagination.PageNumberPagination"
),
"PAGE_SIZE": 20,
"DEFAULT_THROTTLE_RATES": {
"anon": "100/hour",
"user": "1000/hour",
},
}
ModelViewSet for full CRUD@action(detail=True/False) for custom endpointsget_serializer_class() for different read/write serializersget_queryset() to add select_related/prefetch_relatedfrom rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.select_related("category")
permission_classes = [IsAuthenticatedOrReadOnly]
def get_serializer_class(self):
if self.action in ["create", "update", "partial_update"]:
return ProductCreateSerializer
return ProductSerializer
def perform_create(self, serializer):
serializer.save(created_by=self.request.user)
@action(detail=True, methods=["post"])
def publish(self, request, pk=None):
product = self.get_object()
product.status = Product.Status.PUBLISHED
product.save(update_fields=["status"])
return Response({"status": "published"})
ModelSerializer for standard CRUDread_only_fields for computed/auto fieldsvalidate_<field>() or validate() methods@csrf_exempt sparingly|safe with user dataX-Frame-Options middleware enabled by defaultSECURE_SSL_REDIRECT = True in productionSECURE_HSTS_SECONDS in productionSESSION_COOKIE_SECURE = True and CSRF_COOKIE_SECURE = TrueAUTH_PASSWORD_VALIDATORS (enabled by default)django-cors-headers with explicit allowed origins (never CORS_ALLOW_ALL_ORIGINS in production)pytest with pytest-django (not Django's built-in test runner)@pytest.mark.django_dbfactory-boy or fixtures for test dataAPIClient for DRF endpoint testingtest_models.py, test_views.py, test_services.py# conftest.py
import pytest
from rest_framework.test import APIClient
from apps.users.models import User
@pytest.fixture
def api_client():
return APIClient()
@pytest.fixture
def user(db):
return User.objects.create_user(
username="testuser",
email="[email protected]",
password="testpass123",
)
@pytest.fixture
def authenticated_client(api_client, user):
api_client.force_authenticate(user=user)
return api_client
# Development
python manage.py runserver
python manage.py shell_plus # django-extensions
# Migrations
python manage.py makemigrations
python manage.py migrate
python manage.py showmigrations
# Testing
pytest
pytest -v --cov=apps --cov-report=html
pytest apps/products/ -k "test_create"
# Database
python manage.py dbshell
python manage.py dumpdata products > fixtures/products.json
python manage.py loaddata fixtures/products.json
# Static files
python manage.py collectstatic
# Celery
celery -A config worker -l info
celery -A config beat -l info
Base: Django>=5.0, djangorestframework, django-cors-headers, django-filter, djangorestframework-simplejwt, python-decouple, psycopg2-binary, whitenoise
Dev: pytest, pytest-django, pytest-cov, factory-boy, django-debug-toolbar, django-extensions, black, ruff, mypy, django-stubs
select_related and prefetch_related for every queryset@transaction.atomic for multi-step operationsModel.objects.all() without limitsCORS_ALLOW_ALL_ORIGINS = True in production|safe template filter with user-provided dataFor detailed code examples and advanced patterns, see:
development
Zig language guardrails, patterns, and best practices for AI-assisted development. Use when working with Zig files (.zig), build.zig, or when the user mentions Zig. Provides comptime patterns, allocator conventions, C interop guidelines, and testing standards specific to this project's coding standards.
tools
WordPress framework guardrails, patterns, and best practices for AI-assisted development. Use when working with WordPress projects, or when the user mentions WordPress. Provides theme development, plugin architecture, REST API, blocks, and security guidelines.
tools
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs. Use when testing web apps, automating browser interactions, or debugging frontend issues.
tools
Suite of tools for creating elaborate, multi-component web applications using modern frontend technologies (React, Tailwind CSS, shadcn/ui). Use for complex projects requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX pages.