Django Project Structure: A Layer-Oriented Cheat Sheet

  1. manage.py
    • Purpose: Runs Django management commands with the project's settings module configured.
    • Contains: A small command-line wrapper generated by startproject.
    • Example:
      python manage.py check
      python manage.py runserver
  2. config/settings.py
    • Purpose: Defines project configuration such as installed apps, middleware, templates, databases, static files, security settings, and time zone.
    • Example:
      INSTALLED_APPS = [
          'django.contrib.admin',
          'django.contrib.auth',
          'django.contrib.contenttypes',
          'django.contrib.sessions',
          'django.contrib.messages',
          'django.contrib.staticfiles',
          'blog',
      ]
      
      STATIC_URL = 'static/'
  3. config/urls.py
    • Purpose: Defines the project-level URLconf and delegates app routes with include().
    • Contains: URL patterns for admin and app entry points.
    • Example:
      from django.contrib import admin
      from django.urls import include, path
      
      urlpatterns = [
          path('admin/', admin.site.urls),
          path('', include('blog.urls')),
      ]
  4. config/asgi.py and config/wsgi.py
    • Purpose: Exposes callable entry points for ASGI and WSGI servers.
    • Contains: Minimal setup code generated by startproject.
    • Use: ASGI is the entry point for async-capable deployments; WSGI remains common for traditional synchronous deployments.
  5. apps.py
    • Purpose: Defines app configuration.
    • Contains: An AppConfig subclass with the app's import path.
    • Example:
      from django.apps import AppConfig
      
      class BlogConfig(AppConfig):
          name = 'blog'
  6. models.py
    • Purpose: Defines domain data as model classes. Migrations turn model changes into database schema changes.
    • Contains: Classes that extend models.Model, field definitions, relationships, constraints, indexes, and metadata.
    • Example:
      from django.db import models
      
      class Article(models.Model):
          title = models.CharField(max_length=200)
          body = models.TextField()
          published_at = models.DateTimeField(null=True, blank=True)
      
          def __str__(self):
              return self.title
  7. migrations/
    • Purpose: Stores migration files that evolve the database schema over time.
    • Contains: Generated Python files that should be reviewed and committed.
    • Example:
      blog/
          migrations/
              __init__.py
              0001_initial.py
              0002_article_published_at.py
  8. views.py
    • Purpose: Handles requests and returns responses.
    • Contains: Function-based views or class-based views.
    • Example:
      from django.shortcuts import get_object_or_404, render
      from .models import Article
      
      def article_detail(request, article_id):
          article = get_object_or_404(Article, pk=article_id)
          return render(request, 'blog/article_detail.html', {'article': article})
  9. urls.py inside an app
    • Purpose: Maps app-specific paths to views.
    • Contains: URL patterns with stable names for redirects and template links.
    • Example:
      from django.urls import path
      from . import views
      
      app_name = 'blog'
      
      urlpatterns = [
          path('articles/<int:article_id>/', views.article_detail, name='article_detail'),
      ]
  10. templates/
    • Purpose: Stores Django Template Language files.
    • Contains: Project templates, app templates, or both. App templates are commonly namespaced, such as blog/templates/blog/article_detail.html.
    • Example:
      <h1>{{ article.title }}</h1>
      <article>{{ article.body|linebreaks }}</article>
  11. forms.py (Optional)
    • Purpose: Defines forms for validation and user input.
    • Contains: Form or ModelForm classes.
    • Example:
      from django import forms
      from .models import Article
      
      class ArticleForm(forms.ModelForm):
          class Meta:
              model = Article
              fields = ['title', 'body']
  12. admin.py
    • Purpose: Registers and customizes models in the Django admin site.
    • Contains: ModelAdmin classes and registrations.
    • Example:
      from django.contrib import admin
      from .models import Article
      
      @admin.register(Article)
      class ArticleAdmin(admin.ModelAdmin):
          list_display = ['title', 'published_at']
          search_fields = ['title', 'body']
  13. static/ (Optional)
    • Purpose: Stores source static assets such as CSS, JavaScript, images, and downloads.
    • Contains: App-namespaced files, so two apps do not accidentally use the same static path.
    • Example:
      blog/
          static/
              blog/
                  css/site.css
                  js/comments.js
                  images/logo.svg
  14. tests.py or tests/
    • Purpose: Tests models, views, forms, permissions, and integration behavior.
    • Contains: Django TestCase classes or pytest tests, depending on the project.
    • Example:
      from django.test import TestCase
      from .models import Article
      
      class ArticleTests(TestCase):
          def test_str_representation(self):
              article = Article(title='Test', body='Body')
              self.assertEqual(str(article), 'Test')