| name | django |
| description | Best practices for Django web development including models, views, templates, and testing. |
Skill: Django
Best practices for Django web development including models, views, templates, and testing.
When to Use
Apply this skill when working with Django projects — models, views, URL routing, templates, forms, admin, and management commands.
Project Structure
- Follow the standard Django app layout:
models.py, views.py, urls.py, admin.py, tests.py, forms.py.
- Keep each app focused on a single domain concept; avoid "god apps" with unrelated models.
- Use
settings/base.py, settings/dev.py, settings/prod.py for environment-specific configuration.
Models
- Always define
__str__ on models for admin and debugging readability.
- Use
Meta.ordering sparingly — it adds ORDER BY to every query. Prefer explicit .order_by() on querysets.
- Use database indexes (
db_index=True, Meta.indexes) for fields that appear in filter() / order_by().
- Prefer
CharField with choices (or TextChoices / IntegerChoices) over bare strings for constrained fields.
- Use
F() expressions and Q() objects for complex queries to avoid race conditions and improve readability.
Views
- Prefer class-based views (CBVs) for CRUD; prefer function-based views for one-off logic.
- Always explicitly set
queryset or override get_queryset() — never rely on mutable class-level state.
- Use
select_related() and prefetch_related() to avoid N+1 query problems.
- Set
LOGIN_URL and use @login_required / LoginRequiredMixin consistently.
Testing
- Use
pytest-django with @pytest.mark.django_db for database access.
- Prefer
TestCase or TransactionTestCase only when explicit transaction control is needed; otherwise use pytest fixtures.
- Use
RequestFactory or Client to test views without starting a server.
- Use
baker.make() (model-bakery) or factories instead of manual model construction in tests.
Pitfalls
- Never do blocking I/O in async views without wrapping in
sync_to_async.
- Avoid importing models at module level in
settings.py or urls.py (circular imports).
- Never store secrets in
settings.py — use environment variables.
- Avoid raw SQL unless the ORM genuinely cannot express the query.