Creating the Project and Apps
A Django project is the configuration for one top-level site including its settings and top-level URL patterns.
Generate a Project with startproject
To see what Django generates, we'll make a project in a new folder first, beside our repo. We need Django installed before we can generate a project, so we add it as a dependency:
cd ..
mkdir first-django-project
cd first-django-project
uv init --bare
uv add "django~=6.1"
uv init --bare writes a minimal pyproject.toml, and uv add installs Django and adds it there.
We'll use django-admin, Django's command-line tool, to create a project named config in the current directory:
uv run django-admin startproject config .
Warning
The . at the end puts the project in the current directory. Without it, startproject creates a new config/ folder holding manage.py and a second config/ package.
startproject added these to the folder:
├── config/
└── manage.py
manage.py: Runs Django's commands for this project, such asrunserverandstartapp.config/settings.py: The project's configuration.config/urls.py: The top-level URL patterns.config/asgi.pyandconfig/wsgi.py: The entry points for ASGI and WSGI servers, such as Uvicorn and Gunicorn.
Start Django's development server:
uv run manage.py runserver
Open http://127.0.0.1:8000/.
Success
You should see Django's welcome page.
Generate an App with startapp
We generated our site and site settings, but our site has no features.
Site features go into apps.
An app is a Python package that holds one part of a site: its models, views, and URL patterns.
A single project will usually have many apps.
Stop the server with Ctrl+C, and run:
uv run manage.py startapp my_app
startapp gave my_app these files:
models.py: The classes that describe our database tables.admin.py: How those tables appear in Django's admin.views.py: The functions that handle requests and return responses.apps.py: The app's configuration class,MyAppConfig.migrations/: Where Django will keep a history of changes to our tables.
Our Project
This chapter's starting branch provides our project's files. We generated them with the same commands, naming the app animals, then made these changes:
- Added a second app,
accounts, which holds our user model. TheAUTH_USER_MODELsetting names that model. - Added both apps to
INSTALLED_APPS. - Removed the
tests.pyfiles thatstartappgenerates. Our tests come with the exercise's branch, intests/.
Go back to our repo, and check out the starting branch. git stash -u sets aside any changes you've made, new files included:
cd ../django-fundamentals-exercises
git fetch --all
git checkout -b my-ch02-start --no-track origin/ch02-start
uv sync
If Git prints No local changes to save, there was nothing to set aside.
Installed Apps
An app is loaded only when it's listed in INSTALLED_APPS. Ours are at the top of the list in config/settings.py:
INSTALLED_APPS = [
"animals",
"accounts",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
Each app is listed by the name of its package. Django loads the app's configuration class, such as AnimalsConfig, from its apps.py.
Django looks for templates and static files in the installed apps, in order, and uses the first one it finds.
Warning
Forgetting to add a new app here is the most common reason it seems to do nothing. Django only looks for models, migrations, templates, and management commands in installed apps, so a missing app's models never get a table.