Back to Blog

Kickstarting a Modern Django Project (using UV) in 2025

May 7, 2025
William Callahan

Software engineer and entrepreneur based in San Francisco.

Kickstarting a Modern Django Project (using UV) in 2025

Overview: Key Components & Their Roles

This guide covers setting up a modern Django project, including:

  • Django: A Python web framework for rapid development and clean design.
  • Modern Template: Using pre-built templates for a responsive UI/UX.
  • Core Admin Functionality: Implementing user authentication, admin panel, and core product models.
  • SQL Database Integration (PostgreSQL/MySQL): Connecting Django to a relational database.
  • IDE Tooling (VSCode/IntelliJ IDEA): Optimizing development with extensions and configurations.
  • Fast-Start Resources: Libraries and communities to accelerate development.

Part 1: Setting Up Your Initial Django Project

This part covers setting up a standard, default Django project using your preferred workflow (Terminal, VS Code, or PyCharm).

1.1: Getting Started: Prerequisites & Setup

Ensure Python 3 is installed
You'll need Python 3 (ideally a recent version like 3.8 or newer). Check if Python is installed:
bash
python3 --version
If not installed, or you need a different version:
  • Official Website: Download from python.org.
  • Alternative for macOS (and Linux) - Homebrew:

    Use the following command:

    bash
    brew install python3
    
  • Linux: Use your distribution's package manager (e.g., sudo apt update && sudo apt install python3 for Debian/Ubuntu).
  • Windows: Install from the Microsoft Store or python.org. Consider using Windows Subsystem for Linux (WSL).

1.2: Setting Up Your Django Project

Create project & install Django
Create Django project files & run server
Create the project structure:
Access at http://127.0.0.1:8000/. Stop server with Ctrl+C.
Create Superuser (Optional but recommended):
Follow prompts for username/password.

Next Steps

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.

Part 2: Adding Your First App & Core Concepts

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.

Create your first app & configure
Django projects are composed of one or more "apps." An app is a self-contained module that handles a specific piece of functionality.
1. Create the App:

App Naming Tip

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").

2. Register Your App:
Add your new app to INSTALLED_APPS in your project's settings.py file:
python
INSTALLED_APPS = [
    # ... other apps
    'my_first_app', # Or 'my_first_app.apps.MyFirstAppConfig' if using AppConfig
    # ... django apps ...
]
3. Define a Simple Model:
Edit my_first_app/models.py:
python
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
4. Create & Apply Migrations:
Create views and URL configuration
1. Create a View:
Edit my_first_app/views.py:
python
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>")
2. Create App URLs:
Create my_first_app/urls.py:
python
from django.urls import path
from . import views

urlpatterns = [
    path('hello/', views.hello_world, name='hello_world'),
]
3. Include in Project URLs:
Update your project's urls.py (e.g., config/urls.py):
python
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
]
Now visit http://127.0.0.1:8000/app/hello/ to see your view in action.
Key Django concepts
  • Apps for Features: Organize functionality into reusable, modular apps
  • MVT (Model-View-Template): Django's architecture pattern
    • Models - Define data structure and interact with database
    • Views - Handle logic and request/response flow
    • Templates - Present information to users (HTML)
  • URL Routing: Map web addresses to view functions
  • Admin Interface: Built-in data management UI
  • ORM: Object-Relational Mapper for database operations using Python

Part 3: Level Up with Modern Project Templates

Benefits of Modern Templates

These templates reduce boilerplate for common functionalities (auth, UI components, deployment setup), allowing you to focus on your unique application logic.

Setting up a modern template
Most templates provide detailed setup instructions, but here's a general workflow:
1. Generate or Clone the Template:
2. Install Dependencies:
3. Configure Settings:
Adjust environment variables or settings according to template documentation.
4. Run Initial Setup/Migrations:

Part 4: Implementing Core Admin Features with SQL Database

Core Admin Features in Django

Django offers robust features for web applications:

  • User Authentication: django.contrib.auth for user management.
  • Admin Panel: django.contrib.admin for data management.
  • ORM & Models: Django's ORM for database interaction via Python.
Setting up SQL database
1. Choose a Database:
PostgreSQL or MySQL are recommended for production. SQLite (default) works for development.
2. Install Database Drivers:
3. Configure Database in settings.py:
Update the DATABASES dictionary in settings.py:
python
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',
        'USER': 'mydatabaseuser',
        'PASSWORD': 'mypassword',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

Database Credentials Tip

For production, use environment variables for database credentials, not hardcoded values:

python
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 panel configuration
Django's admin panel provides a powerful interface for managing your application's data.
1. Register Models in admin.py:
In your app's admin.py file:
python
from django.contrib import admin
from .models import Greeting

@admin.register(Greeting)
class GreetingAdmin(admin.ModelAdmin):
    list_display = ('message', 'created_at')
    search_fields = ('message',)
2. Access Admin Interface:
After starting the development server, visit http://127.0.0.1:8000/admin/ and log in with superuser credentials.
Admin Customization Options:
  • list_display: Fields to show in list view
  • search_fields: Fields to search through
  • list_filter: Enable filtering by fields
  • fieldsets: Organize fields in detail view
  • readonly_fields: Fields that can't be edited

Part 5: Essential Django Commands

Execute from project root with virtual environment active.

Beyond Development: Deployment Considerations

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

Part 6: Troubleshooting Common Issues

Development server issues
Stopping the Server:
  • Clean Stop: Ctrl+C in the terminal
  • If Ctrl+Z was used: Use fg then Ctrl+C, or jobs and kill %JOB_NUMBER
Address Already in Use:
If you see "Address already in use," find and kill the process:
bash
# Find the process using port 8000
lsof -i :8000

# Kill the process
kill <PID>
Migration issues
"No changes detected":
  • Check that your app is in INSTALLED_APPS
  • Verify you saved all changes to models.py
  • Ensure you're specifying the correct app name in the command
Migration Errors:
  • Verify database connection settings
  • Check for syntax errors in models
  • View migration status with python manage.py showmigrations
Static files & templates
Static Files Not Loading (404s):
  • Development: Check STATIC_URL, ensure files are in app_name/static/app_name/
  • Production: Run collectstatic, configure web server for STATIC_ROOT
TemplateDoesNotExist Error:
  • Verify app is in INSTALLED_APPS
  • Check template path - should be in app_name/templates/app_name/
  • Check for typos in template names
Import & package issues
ModuleNotFoundError:
  • Ensure virtual environment is activated
  • Check if package is installed:
Other Import Issues:
  • Check for typos in import statements
  • Verify proper Python package structure
  • Beware of circular imports
Database debugging
Connection Problems:
  • Verify database settings in settings.py
  • Ensure database server is running
  • Check firewall settings
  • Confirm correct driver is installed
Using Django Shell for Debugging:
Example shell session for debugging models:
python
# Import your model
from my_first_app.models import Greeting

# Query data
Greeting.objects.all()

# Create test data
Greeting.objects.create(message="Hello, Django!")