Skip to content

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:

shell
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:

shell
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:

Text
├── config/
└── manage.py
  • manage.py: Runs Django's commands for this project, such as runserver and startapp.
  • config/settings.py: The project's configuration.
  • config/urls.py: The top-level URL patterns.
  • config/asgi.py and config/wsgi.py: The entry points for ASGI and WSGI servers, such as Uvicorn and Gunicorn.

Start Django's development server:

shell
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:

shell
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. The AUTH_USER_MODEL setting names that model.
  • Added both apps to INSTALLED_APPS.
  • Removed the tests.py files that startapp generates. Our tests come with the exercise's branch, in tests/.

Go back to our repo, and check out the starting branch. git stash -u sets aside any changes you've made, new files included:

shell
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:

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.