Kickstarting a Modern Django Project (using UV) in 2025
Software engineer and entrepreneur based in San Francisco.
Software engineer and entrepreneur based in San Francisco.
This guide covers setting up a modern Django project, including:
This part covers setting up a standard, default Django project using your preferred workflow (Terminal, VS Code, or PyCharm).
python3 --version
Alternative for macOS (and Linux) - Homebrew:
Use the following command:
brew install python3
sudo apt update && sudo apt install python3
for Debian/Ubuntu).uv
is an extremely fast Python package installer and resolver, written in Rust. It's designed as a modern, high-performance alternative to tools like
pip
(the standard installer from PyPI, the Python Package Index) and Conda (a broader package and environment manager). uv
aims to replace pip
, pip-tools
, and venv
.
Select only one of the installation methods below. The official Astral install script (the first option) is generally preferred for most users.
curl -LsSf https://astral.sh/uv/install.sh | sh
Alternatively, for Windows PowerShell (if the above doesn't work directly):
irm https://astral.sh/uv/install.ps1 | iex
brew install uv
cargo install uv
pip install uv
After installation, verify with: uv --version
For more details, see the
official uv
installation guide.
pip
is the standard package installer for Python. venv
is the standard module for creating lightweight virtual environments.pip
is usually included with Python installations (version 3.4+). To ensure it's up-to-date:python3 -m ensurepip --upgrade
python3 -m pip install --upgrade pip
pip
:pip3 --version # or pip --version
venv
is part of the Python standard library (Python 3.3+). To create a virtual environment:python3 -m venv .venv
source .venv/bin/activate
.venv\Scripts\activate.bat
.venv\Scripts\Activate.ps1
# 1. Create project directory and setup environment
mkdir my_django_project && cd my_django_project
uv venv
# `uv venv` creates a lightweight virtual environment in the .venv directory,
# isolating project dependencies from the system Python installation.
# For more details on how uv manages Python environments, see the official documentation: https://docs.astral.sh/uv/pip/environments/
uv init --bare --python-pin
# `uv init` sets up the project for uv's dependency management, creating
# a minimal pyproject.toml and a .python-version file. This is where
# uv will track dependencies and can generate a uv.lock file for
# reproducible builds.
# 2. Install Django
uv add django
# `uv add` installs the specified package (Django) and automatically
# updates pyproject.toml and uv.lock to reflect the new dependency
# and its exact version and dependencies.
# 3. Verify installation
uv run django-admin --version
# `uv run` executes a command within the project's virtual environment.
# This means you don't need to explicitly activate the environment
# with `source .venv/bin/activate` (or similar) every time you open a new terminal,
# unlike common workflows with `pip` and `venv`.
# 1. Create project directory and setup environment
mkdir my_django_project && cd my_django_project
python3 -m venv .venv
source .venv/bin/activate # On Windows: .\.venv\Scripts\activate
# 2. Install Django
pip install django
# 3. Verify installation
django-admin --version
# Create project files (replace "config" with preferred name)
uv run django-admin startproject config .
# Apply initial migrations
uv run manage.py migrate
# This command applies database migrations, setting up the necessary tables.
# By default, Django uses an SQLite database stored in a file named db.sqlite3
# in your project's root directory if no other database is configured.
# Run development server
uv run manage.py runserver
# This starts Django's built-in development web server.
# Create project files (replace "config" with preferred name)
django-admin startproject config .
# Apply initial migrations
python manage.py migrate
# This command applies database migrations, setting up the necessary tables.
# By default, Django uses an SQLite database stored in a file named db.sqlite3
# in your project's root directory if no other database is configured.
# Run development server
python manage.py runserver
# This starts Django's built-in development web server.
http://127.0.0.1:8000/
. Stop server with Ctrl+C
.uv run manage.py createsuperuser
python manage.py createsuperuser
.vscode/launch.json
for debuggingIf the project wizard (like in PyCharm) automatically sets up uv
and a pyproject.toml
file, you typically just need to run uv sync
in the project directory to install the defined packages. After that, you can use uv run
for all your commands (e.g., uv run manage.py migrate
), as uv automatically handles the virtual environment activation.
Now that you have a basic Django project running using your preferred setup method, the next sections will cover creating your first app and using modern project templates.
A Django project is the overall container for your application's settings and configurations (e.g., database settings, installed apps, URL routing at the project level). A project can contain multiple apps, which are modular components that handle specific functionalities (like a blog, a user management system, etc.). Think of the project as the building and apps as the distinct rooms or services within it.
With the default project running, let's create your first Django app and understand core concepts.
uv run manage.py startapp my_first_app
python manage.py startapp my_first_app
When naming your Django app, it may be required to use lowercase alphabet-only characters and avoid special characters like underscores (e.g., avoid "my_first_app").
INSTALLED_APPS
in your project's settings.py
file:INSTALLED_APPS = [
# ... other apps
'my_first_app', # Or 'my_first_app.apps.MyFirstAppConfig' if using AppConfig
# ... django apps ...
]
my_first_app/models.py
:from django.db import models
class Greeting(models.Model):
message = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.message
# Generate migration files
uv run manage.py makemigrations my_first_app
# Apply migrations to database
uv run manage.py migrate
# Generate migration files
python manage.py makemigrations my_first_app
# Apply migrations to database
python manage.py migrate
my_first_app/views.py
:from django.http import HttpResponse
from .models import Greeting
def hello_world(request):
greeting = Greeting.objects.first() # Get the first greeting, or None
if not greeting:
greeting_text = "No greetings yet!"
else:
greeting_text = greeting.message
return HttpResponse(f"<h1>{greeting_text}</h1><p>From my_first_app!</p>")
my_first_app/urls.py
:from django.urls import path
from . import views
urlpatterns = [
path('hello/', views.hello_world, name='hello_world'),
]
urls.py
(e.g., config/urls.py
):from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('app/', include('my_first_app.urls')), # This adds your app URLs
]
http://127.0.0.1:8000/app/hello/
to see your view in action.These templates reduce boilerplate for common functionalities (auth, UI components, deployment setup), allowing you to focus on your unique application logic.
# Install cookiecutter if needed
uv add cookiecutter
# Generate project from template
uv run cookiecutter gh:cookiecutter/cookiecutter-django
# Install cookiecutter if needed
pip install cookiecutter
# Generate project from template
cookiecutter gh:cookiecutter/cookiecutter-django
# Clone directly from repository
git clone <repository_url> my_modern_project
cd my_modern_project
# Sync dependencies using uv
uv sync
# `uv sync` installs the exact dependencies specified in the uv.lock file,
# ensuring that everyone working on the project has the same environment.
# Install dependencies using Poetry
poetry install
# Install dependencies using PDM
pdm install
# Using uv with a new virtual environment
uv venv
uv pip install -r requirements.txt
# Or import into existing uv project
uv add -r requirements.txt
# Create and activate virtual environment
python3 -m venv .venv
source .venv/bin/activate # On Windows: .\.venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Build and start containers
docker-compose up --build
uv run manage.py migrate
python manage.py migrate
docker-compose exec web python manage.py migrate
Django offers robust features for web applications:
django.contrib.auth
for user management.django.contrib.admin
for data management.uv add psycopg2-binary
pip install psycopg2-binary
uv add mysqlclient
pip install mysqlclient
DATABASES
dictionary in settings.py
:DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
For production, use environment variables for database credentials, not hardcoded values:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DB_NAME', 'mydatabase'),
'USER': os.environ.get('DB_USER', 'mydatabaseuser'),
'PASSWORD': os.environ.get('DB_PASSWORD', 'mypassword'),
'HOST': os.environ.get('DB_HOST', '127.0.0.1'),
'PORT': os.environ.get('DB_PORT', '5432'),
}
}
admin.py
file:from django.contrib import admin
from .models import Greeting
@admin.register(Greeting)
class GreetingAdmin(admin.ModelAdmin):
list_display = ('message', 'created_at')
search_fields = ('message',)
http://127.0.0.1:8000/admin/
and log in with superuser credentials.list_display
: Fields to show in list viewsearch_fields
: Fields to search throughlist_filter
: Enable filtering by fieldsfieldsets
: Organize fields in detail viewreadonly_fields
: Fields that can't be editedExecute from project root with virtual environment active.
# Start development server
uv run manage.py runserver
# Optional: specify port
uv run manage.py runserver 8080
# Start development server
python manage.py runserver
# Optional: specify port
python manage.py runserver 8080
# Create migrations based on model changes
uv run manage.py makemigrations
# Apply migrations to the database
uv run manage.py migrate
# Show migration status
uv run manage.py showmigrations
# Create migrations based on model changes
python manage.py makemigrations
# Apply migrations to the database
python manage.py migrate
# Show migration status
python manage.py showmigrations
# Create superuser (admin)
uv run manage.py createsuperuser
# Change user password
uv run manage.py changepassword username
# Create superuser (admin)
python manage.py createsuperuser
# Change user password
python manage.py changepassword username
# Start interactive Python shell with Django context
uv run manage.py shell
# Run tests
uv run manage.py test
# Run specific tests
uv run manage.py test app_name.tests.test_module
# Start interactive Python shell with Django context
python manage.py shell
# Run tests
python manage.py test
# Run specific tests
python manage.py test app_name.tests.test_module
# Collect static files to STATIC_ROOT
uv run manage.py collectstatic
# Find unused static files
uv run manage.py findstatic --first filename.ext
# Collect static files to STATIC_ROOT
python manage.py collectstatic
# Find unused static files
python manage.py findstatic --first filename.ext
While this guide focuses on setting up your local development environment, deploying your Django application to a production server involves additional steps. Unlike the built-in development server, production deployments typically use a Web Server Gateway Interface (WSGI) server (like Gunicorn or uWSGI) to handle requests, often in conjunction with a web proxy server (like Nginx or Apache, or AWS Lambda).
For a deeper dive into some deployment strategies and easy deployment options, I made a recent past sharing my current hosting preferences: How I Host My Apps: How to Deploy in 2025
Ctrl+C
in the terminalCtrl+Z
was used: Use fg
then Ctrl+C
, or jobs
and kill %JOB_NUMBER
# Find the process using port 8000
lsof -i :8000
# Kill the process
kill <PID>
INSTALLED_APPS
models.py
python manage.py showmigrations
STATIC_URL
, ensure files are in app_name/static/app_name/
collectstatic
, configure web server for STATIC_ROOT
TemplateDoesNotExist
Error:INSTALLED_APPS
app_name/templates/app_name/
# Install package
uv add <package_name>
# Verify installed packages
uv pip list
# Install package
pip install <package_name>
# Verify installed packages
pip list
settings.py
uv run manage.py shell
python manage.py shell
# Import your model
from my_first_app.models import Greeting
# Query data
Greeting.objects.all()
# Create test data
Greeting.objects.create(message="Hello, Django!")