
Understanding Django Project Structure
Welcome! If you’re just starting out with Django, you might wonder what all those files and folders are for. Fear not—today we’ll walk through the standard Django project structure, demystifying each component. By the end, you’ll feel right at home working within a Django project.
Let’s start by creating a new project. Open your terminal and run the following command:
django-admin startproject myproject
This command will create a new directory named myproject
with the following structure:
myproject/
manage.py
myproject/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
Let’s break down each of these files and folders.
The Outer myproject Directory
This is the root directory of your project. It can be renamed to anything you like (for example, myblog
or mysite
). It’s simply a container for your project.
The Inner myproject Directory
This is the actual Python package for your project. Its name is what you’ll use to import anything inside it (e.g., import myproject.settings
).
manage.py
This is a command-line utility that lets you interact with your Django project. You’ll use it to run the development server, create apps, run tests, and more. For example:
python manage.py runserver
Starts the development server.
Inside the Inner myproject Directory
Now, let’s look at the files inside the inner myproject
directory.
init.py
This file tells Python that this directory should be considered a Python package. It’s usually empty, but you can use it to execute initialization code for the package.
settings.py
This is one of the most important files in your project. It contains all the configuration for your Django project. Here, you’ll set things like installed apps, database configuration, static files settings, and more.
For example, to add a new app to your project, you would add it to the INSTALLED_APPS
list:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp', # Your custom app
]
urls.py
This file is responsible for mapping URLs to views. It’s the entry point for the URL dispatcher. Here’s a simple example:
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('about/', views.about, name='about'),
]
wsgi.py and asgi.py
These files are entry points for WSGI and ASGI servers, respectively. They are used to deploy your project to a production server. You typically won’t need to modify these files unless you’re doing advanced deployment configurations.
Django Apps: The Building Blocks
A Django project is made up of one or more apps. An app is a self-contained module that encapsulates a specific functionality of your project. For example, you might have an app for user authentication, another for blogging, and so on.
To create a new app, run:
python manage.py startapp myapp
This will create a new directory myapp
with the following structure:
myapp/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
Let’s explore each of these files.
models.py
This is where you define your database models. Each model is a Python class that subclasses django.db.models.Model
. Here’s an example:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
published_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
views.py
Views are where you write the logic for your web pages. A view function takes a web request and returns a web response. Here’s a simple view:
from django.http import HttpResponse
def home(request):
return HttpResponse("Welcome to the home page!")
urls.py (in the app)
While the project has a urls.py
file, each app can also have its own urls.py
to manage its URLs. This helps keep your code organized. For example, in myapp/urls.py
:
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
]
And then include it in the project’s urls.py
:
from django.urls import include, path
urlpatterns = [
path('myapp/', include('myapp.urls')),
]
admin.py
This file is used to register your models with the Django admin interface. The admin interface is a powerful built-in tool for managing your site’s content. Here’s how you register a model:
from django.contrib import admin
from .models import Post
admin.site.register(Post)
migrations/
This directory contains database migration files. Migrations are how Django propagates changes you make to your models (like adding a field) into the database schema. You don’t need to create these files manually—Django generates them when you run:
python manage.py makemigrations
And then apply them with:
python manage.py migrate
tests.py
This is where you write tests for your app. Testing is a crucial part of development, and Django makes it easy to write and run tests. Here’s a simple test:
from django.test import TestCase
from .models import Post
class PostModelTest(TestCase):
def test_create_post(self):
post = Post.objects.create(title="Test", content="Test content")
self.assertEqual(post.title, "Test")
apps.py
This file contains configuration for the app itself. You usually won’t need to modify this, but it’s where you can set the default name of the app.
Static and Media Files
Django also handles static files (like CSS, JavaScript, and images) and media files (user-uploaded files). Here’s how you can set them up.
Static Files
In settings.py
, you define where your static files are located:
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / "static"]
Then, create a static
directory in your project root and place your static files there.
Media Files
For media files, add these settings:
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / "media"
Don’t forget to serve these files in development by adding to your urls.py
:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... your URL patterns
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Templates
Templates are HTML files with special Django template tags. By default, Django looks for templates in a templates
directory in each app. You can also set a global templates directory in settings.py
:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / "templates"],
# ...
},
]
Then, create a templates
directory in your project root and place your base templates there.
Environment Variables
It’s a good practice to keep sensitive information like secret keys and database passwords out of your codebase. You can use environment variables for this. Install the python-dotenv
package:
pip install python-dotenv
Then, create a .env
file in your project root:
SECRET_KEY=your_secret_key_here
DEBUG=True
And in settings.py
, load these variables:
from dotenv import load_dotenv
import os
load_dotenv()
SECRET_KEY = os.getenv('SECRET_KEY')
DEBUG = os.getenv('DEBUG') == 'True'
Example Project Structure
Here’s an example of a more complex project structure:
myproject/
manage.py
.env
requirements.txt
static/
css/
js/
images/
media/
templates/
base.html
home.html
myproject/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
blog/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
urls.py
templates/
blog/
post_list.html
post_detail.html
users/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
templates/
users/
login.html
register.html
Key Configuration Settings
Let’s look at some important settings in settings.py
that you should be aware of.
DEBUG: Should be True
in development and False
in production. Never deploy with DEBUG=True
.
ALLOWED_HOSTS: A list of strings representing the host/domain names that this Django site can serve. This is a security measure to prevent HTTP Host header attacks.
DATABASES: The database configuration. By default, Django uses SQLite, but you can switch to PostgreSQL, MySQL, etc.
INSTALLED_APPS: A list of strings designating all applications that are enabled in this Django installation.
MIDDLEWARE: A list of middleware to use. Middleware is a framework of hooks into Django’s request/response processing.
ROOT_URLCONF: The full Python path to the root URLconf.
TEMPLATES: Configuration for the template engine.
WSGI_APPLICATION: The full Python path to the WSGI application object that Django’s built-in servers will use.
Common Commands
Here are some common commands you’ll use while working with Django:
python manage.py runserver
: Starts the development server.python manage.py startapp appname
: Creates a new app.python manage.py makemigrations
: Creates new migrations based on changes to models.python manage.py migrate
: Applies migrations to the database.python manage.py createsuperuser
: Creates a superuser for the admin interface.python manage.py collectstatic
: Collects static files for production.
Best Practices
- Keep each app focused on a single functionality.
- Use environment variables for sensitive settings.
- Write tests for your apps.
- Use version control (like Git) for your project.
- Regularly update your dependencies.
Troubleshooting Tips
If you run into issues, here are some things to check:
- Make sure all apps are added to
INSTALLED_APPS
. - Check that your database migrations are up to date.
- Verify that your URLs are correctly configured.
- Ensure that your static and media files are properly set up.
I hope this guide has helped you understand the Django project structure. Happy coding!
File/Folder | Purpose |
---|---|
manage.py | Command-line utility for project management |
settings.py | Project configuration (databases, apps, middleware, etc.) |
urls.py | URL declarations for the project; a “table of contents” of your Django-powered site |
wsgi.py | Entry point for WSGI-compatible web servers to serve your project |
asgi.py | Entry point for ASGI-compatible web servers to serve your project |
models.py | Database models for the app |
views.py | Logic for handling requests and returning responses |
admin.py | Configuration for the Django admin interface |
migrations/ | Database migration files |
tests.py | Test cases for the app |
apps.py | Configuration for the app itself |
Key takeaways: - A Django project is a collection of configuration and apps. - An app is a web application that does something specific. - The project handles overall configuration, while apps handle specific functionalities. - Always keep sensitive information in environment variables. - Use migrations to manage database schema changes.