Django projects follow a predictable layout and a handful of naming conventions. Once you know them, you can open almost any Django codebase and find your way around quickly. This chapter covers the files in a project and an app, the settings module, and the conventions most teams follow.
Project and app files
Running django-admin startproject mysite . and python manage.py startapp polls gives you this layout:
mysite-project/
manage.py
mysite/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
polls/
__init__.py
admin.py
apps.py
models.py
tests.py
views.py
migrations/
__init__.py
startapp does not create urls.py, forms.py, templates/ or static/; add them when you need them.
Where templates and static files live
By default Django looks for files in each app's templates/ and static/ folders. To avoid name clashes between apps, the convention is to nest them in one more folder named after the app.
polls/
templates/
polls/
index.html
detail.html
static/
polls/
style.css
Views then refer to "polls/index.html", and templates load {% static 'polls/style.css' %}, both prefixed with the app name. Shared templates used across apps, such as base.html, usually go in a project-level templates/ folder that you add to DIRS.
A tour of settings.py
settings.py is an ordinary Python module. These are the settings you will touch most often:
# mysite/settings.py (excerpt)
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = "dev-only-placeholder"
DEBUG = True
ALLOWED_HOSTS = []
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_TZ = True
STATIC_URL = "static/"
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
BASE_DIR is the folder that contains manage.py. With USE_TZ = True, datetimes are stored in UTC and converted to TIME_ZONE for display. DEFAULT_AUTO_FIELD sets the type of the auto-incrementing primary key added to models that do not declare one.
Separating settings per environment
Never hard-code SECRET_KEY or database passwords. The simplest fix is to read them from environment variables.
# mysite/settings.py
import os
SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY", "dev-only-placeholder")
DEBUG = os.environ.get("DJANGO_DEBUG", "") == "1"
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "localhost,127.0.0.1").split(",")
As settings grow, many teams turn settings.py into a settings/ package with base.py, dev.py and prod.py, and pick one at runtime through the DJANGO_SETTINGS_MODULE environment variable. Packages such as django-environ can also load values from a .env file.
# Run a management command with the production settings
DJANGO_SETTINGS_MODULE=mysite.settings.prod python manage.py check --deploy
Commands you run through manage.py
You can add your own commands too: create a management/commands/ folder in an app and put a class that subclasses BaseCommand in it. It then runs through manage.py like any built-in command.
Summary
- The project folder holds
manage.py and the settings package; each app holds its models, views, admin and migrations. - Nest templates and static files in a folder named after the app to avoid clashes.
- Pass secrets through environment variables and split settings per environment when needed.
- Automate routine work with
manage.py commands, including custom ones.
0 条评论
登录 · 登录后即可发表评论。