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
- Your First Django Project —
hello-django/withconfig/andblog/ - Virtual environment activated
Top-Level Layout
Code explanation:
- Project package (
config/) — site-wide configuration, root URL routing - App (
blog/) — feature code you write and reuse - Optional
templates/andstatic/at project root when shared across apps
manage.py
#!/usr/bin/env python
import os
import sys
def main():
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
...| Role | Detail |
|---|---|
| CLI entry | python manage.py runserver, migrate, test |
| Settings module | Sets DJANGO_SETTINGS_MODULE to config.settings |
| Do not edit often | Regenerated 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):
| Setting | Purpose |
|---|---|
SECRET_KEY | Cryptographic signing (sessions, CSRF tokens) |
DEBUG | True in dev — verbose errors; must be False in production |
ALLOWED_HOSTS | Hostnames the site may serve (empty when DEBUG=True) |
INSTALLED_APPS | Enabled Django and project apps |
MIDDLEWARE | Request/response pipeline (security, sessions, auth) |
ROOT_URLCONF | Module path to root urls.py ("config.urls") |
DATABASES | Default SQLite db.sqlite3 in dev |
TEMPLATES | Template engine, directories, context processors |
STATIC_URL | URL prefix for static assets ("static/") |
DEFAULT_AUTO_FIELD | Primary 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:
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("blog.urls")),
]ROOT_URLCONF in settings must point here (config.urls).
wsgi.py and asgi.py
| File | Interface | Used by |
|---|---|---|
wsgi.py | WSGI | Gunicorn, uWSGI — typical sync deploy |
asgi.py | ASGI | Uvicorn, Daphne — async / WebSockets |
Both expose application callable. Production servers import:
config.wsgi:application
config.asgi:applicationDevelopment runserver uses these internally; you rarely import them manually while learning.
Application Package: blog/
apps.py
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:
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
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| Question | Answer |
|---|---|
| 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.py → DATABASES |
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):
# 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:
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"]Production uses collectstatic — Static and Media.
BASE_DIR
Fresh settings.py includes:
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parentCode explanation:
BASE_DIR= project root (folder withmanage.py)- Use
BASE_DIR / "templates"for portable paths on Windows and Linux
Middleware Pipeline (Preview)
Default MIDDLEWARE order matters:
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
HTTP GET /
→ ROOT_URLCONF (config.urls)
→ include("blog.urls")
→ path("", views.home)
→ blog.views.home(request)
→ HttpResponseMatches the diagram in What Is Django.
Adding a Second App (Pattern)
python manage.py startapp accountsAdd "accounts" to INSTALLED_APPS, create accounts/urls.py, include in config/urls.py:
path("accounts/", include("accounts.urls")),Keeps each feature isolated—same pattern as blog.
Post-Chapter Checklist
- You can explain
manage.pyvsconfig/settings.py - You know
views.pyvsmodels.pyvsurls.py - You understand project (config) vs app (blog)
- You know
migrations/purpose andwsgi.pyrole in deploy - You can find
INSTALLED_APPS,DATABASES,TEMPLATESin 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.