Project Structure and Settings Overview

Introduction

Chapter 03 created a working site with a handful of files. This chapter walks through every important path in a Django project—what manage.py, settings.py, wsgi.py, and each app file does—so you know where to edit when adding models, URLs, or deploy config. Detailed multi-environment settings come in the next chapter.

Prerequisites

Top-Level Layout

Code explanation:

  • Project package (config/) — site-wide configuration, root URL routing
  • App (blog/) — feature code you write and reuse
  • Optional templates/ and static/ at project root when shared across apps

manage.py

python
#!/usr/bin/env python
import os
import sys
 
def main():
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
    ...
RoleDetail
CLI entrypython manage.py runserver, migrate, test
Settings moduleSets DJANGO_SETTINGS_MODULE to config.settings
Do not edit oftenRegenerated by startproject; rarely customized

Run all Django commands from the directory containing manage.py.

Project Package: config/

settings.py

Central configuration dictionary. Key groups (defaults in a fresh Django 5 project):

SettingPurpose
SECRET_KEYCryptographic signing (sessions, CSRF tokens)
DEBUGTrue in dev — verbose errors; must be False in production
ALLOWED_HOSTSHostnames the site may serve (empty when DEBUG=True)
INSTALLED_APPSEnabled Django and project apps
MIDDLEWARERequest/response pipeline (security, sessions, auth)
ROOT_URLCONFModule path to root urls.py ("config.urls")
DATABASESDefault SQLite db.sqlite3 in dev
TEMPLATESTemplate engine, directories, context processors
STATIC_URLURL prefix for static assets ("static/")
DEFAULT_AUTO_FIELDPrimary key type for models (BigAutoField)

Full tour of dev vs production values: Settings and Multi-Environment.

urls.py (root URLconf)

Maps URL paths to views or included app URLconfs:

python
urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("blog.urls")),
]

ROOT_URLCONF in settings must point here (config.urls).

wsgi.py and asgi.py

FileInterfaceUsed by
wsgi.pyWSGIGunicorn, uWSGI — typical sync deploy
asgi.pyASGIUvicorn, Daphne — async / WebSockets

Both expose application callable. Production servers import:

text
config.wsgi:application
config.asgi:application

Development runserver uses these internally; you rarely import them manually while learning.

Application Package: blog/

apps.py

python
from django.apps import AppConfig
 
class BlogConfig(AppConfig):
    default_auto_field = "django.db.models.BigAutoField"
    name = "blog"

Modern style registers the app in INSTALLED_APPS as "blog.apps.BlogConfig" (optional; "blog" shorthand still works).

Use ready() for startup hooks (signals)—advanced; avoid heavy work there in beginners’ projects.

models.py

Defines ORM models (database tables as Python classes). Empty until you add models in chapter 09.

views.py

Request handlers — functions or classes returning HttpResponse, render(), JsonResponse, etc.

urls.py (app-level)

URL patterns for this app only. Included from root config/urls.py with include().

admin.py

Register models with Django Admin:

python
from django.contrib import admin
# from .models import Post
# admin.site.register(Post)

Used in Django Admin.

migrations/

Auto-generated Python files describing schema changes. Do not hand-edit applied migrations in teams—use makemigrations / migrate.

Initially contains __init__.py only.

tests.py

Home for TestCase classes. Run with python manage.py test.

Project vs Application

text
  Project (config)                 Apps (blog, users, shop)
  ─────────────────                ────────────────────────
  settings.py                      models.py, views.py
  root urls.py                     app urls.py
  wsgi.py / asgi.py                admin.py, tests.py
  one per deployment               many per project
QuestionAnswer
Where do I add a blog post model?blog/models.py
Where do I mount /blog/ URLs?blog/urls.py, included from config/urls.py
Where is the database configured?config/settings.pyDATABASES
Can I reuse blog in another site?Yes—copy app or publish package; new project INSTALLED_APPS

Optional: Project-Level templates/ and static/

templates/

Shared layouts (e.g. templates/base.html):

python
# settings.py TEMPLATES excerpt
"DIRS": [BASE_DIR / "templates"],
"APP_DIRS": True,

App-specific templates go in blog/templates/blog/ (namespaced by app name—best practice).

static/

Project-wide CSS/JS when not tied to one app:

python
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"]

Production uses collectstaticStatic and Media.

BASE_DIR

Fresh settings.py includes:

python
from pathlib import Path
 
BASE_DIR = Path(__file__).resolve().parent.parent

Code explanation:

  • BASE_DIR = project root (folder with manage.py)
  • Use BASE_DIR / "templates" for portable paths on Windows and Linux

Middleware Pipeline (Preview)

Default MIDDLEWARE order matters:

text
Request  → Security → Session → Common → CSRF → Auth → Messages → XFrame
         → View
Response ← (reverse order)

You will customize middleware rarely at first. Security and CSRF are enabled by default—good for learning correct form habits early.

How a Request Finds Your View

text
HTTP GET /
    → ROOT_URLCONF (config.urls)
    → include("blog.urls")
    → path("", views.home)
    → blog.views.home(request)
    → HttpResponse

Matches the diagram in What Is Django.

Adding a Second App (Pattern)

bash
python manage.py startapp accounts

Add "accounts" to INSTALLED_APPS, create accounts/urls.py, include in config/urls.py:

python
path("accounts/", include("accounts.urls")),

Keeps each feature isolated—same pattern as blog.

Post-Chapter Checklist

  • You can explain manage.py vs config/settings.py
  • You know views.py vs models.py vs urls.py
  • You understand project (config) vs app (blog)
  • You know migrations/ purpose and wsgi.py role in deploy
  • You can find INSTALLED_APPS, DATABASES, TEMPLATES in settings

FAQ

Rename config to mysite?

Possible but touches imports (DJANGO_SETTINGS_MODULE, ROOT_URLCONF). Pick a name at startproject and keep it.

Delete asgi.py if I only use WSGI?

Leave it—harmless; default deploy uses wsgi.py.

Where does db.sqlite3 appear?

After first migrate with default DATABASES — not required for Hello view only.

One repo, multiple apps?

Normal. One project, many apps in one Git repo.

Is apps.py required?

Django creates it; use BlogConfig in INSTALLED_APPS for explicit app config.