Copy-paste Claude Code prompts for Django 5 models, safe migrations, DRF serializers, N+1 query fixes, and select_related optimisation. Battle-tested 2026.
Django's strength — convention over configuration — is exactly what makes Claude Code so effective on Django repos: the conventions act as guardrails. The prompts below give Claude the right scope so it builds models, migrations, and DRF endpoints that match your existing patterns rather than freelancing.
Add a new model 'Invoice' to the billing app.
Fields:
- customer (FK to customers.Customer, on_delete=PROTECT)
- amount_cents (PositiveIntegerField)
- currency (CharField(3), choices=billing.currencies.ISO_4217)
- status (CharField, choices=billing.invoice_status.STATUSES, default='draft')
- issued_at (DateTimeField, null=True)
- created_at, updated_at (auto)
Constraints:
- Read billing/models.py first for the existing pattern (TimeStampedModel base?).
- Match indentation, import order, and field ordering used by the existing Charge model.
- Add a Meta.indexes entry on (customer, status) — that's the hot read path.
- Generate the migration with --name add_invoice. Do NOT run migrate.
- Add a basic admin.py registration matching the existing Charge admin.
- Add a DRF ModelSerializer in billing/serializers.py and ViewSet in views.py
registered in urls.py — same patterns as ChargeViewSet.
Do not write tests yet; I'll prompt for those after I review the diff.
Why it works: the "read X first" line forces Claude to load the existing pattern before generating. Without it, Claude defaults to a generic Django style that may not match your project's conventions.
I need to rename the column 'amt' to 'amount_cents' on billing.Invoice in
production without downtime. There are ~12M rows.
Produce a sequence of migrations that:
1. Adds the new column 'amount_cents' nullable, no default (cheap).
2. Backfills in a separate RunPython migration with .iterator(chunk_size=5000)
to avoid memory blowup. Wrap in transaction.atomic per chunk.
3. Sets NOT NULL on the new column.
4. Updates the Django model field to point at the new column.
5. Drops the old column (separate migration — deploy step 4 first).
Each step = one migration file. Number them so I can deploy 1-2-3 → release → 4 → release → 5.
Do not combine. Do not use AlterField rename — that takes a write lock on Postgres.
Profile the InvoiceListView (billing/views.py) — django-debug-toolbar shows
~140 queries for a 20-row page. Find the N+1 sources.
Constraints:
- Read the serializer used by the view first.
- For each related access (FK, M2M, reverse), decide select_related vs prefetch_related.
- Output a unified diff for ONE file at a time. Show the queryset change and explain
in 1 line why select vs prefetch.
- Verify by mentally walking through: with these joins, how many queries remain?
State that number.
billing/ — invoices, charges. customers/ — orgs, users. NEVER cross-import models; use FK string refs. One paragraph saves 30 prompts.## Testing section: pytest-django, factories live in tests/factories.py, never call .objects.create() in tests — use the factory.Related: calling the Claude API from Django, testing prompts, refactoring prompts.