Static And Media Configuration
Configure STATIC_URL, STATICFILES_DIRS, STATIC_ROOT, MEDIA_URL, and MEDIA_ROOT. Understand collectstatic, where files live in dev and prod, and how this ties into settings.
1. Introduction
Django separates files into two categories: static files and media files. Static files are part of your codebase — CSS, JavaScript, and images you write or include yourself. Media files are uploaded by users at runtime — profile photos, documents, attachments.
Each category has its own set of settings and behaves differently in development vs production. This guide covers both, step by step.
- You should already have
myprojectset up withdjango.contrib.staticfilesinINSTALLED_APPS. - Your
.venvmust be active and Django 5.2 installed.
2. Static files settings
Add these settings to mysite/settings/base.py:
# mysite/settings/base.py
STATIC_URL = 'static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
STATIC_ROOT = BASE_DIR / 'staticfiles'
Here is what each setting does:
STATIC_URL— the URL prefix Django uses when generating links to static files. For example/static/css/main.css.STATICFILES_DIRS— a list of folders where Django looks for static files during development. We point it to the project-levelstatic/folder. Django also automatically finds static files inside each app'sstatic/subfolder.STATIC_ROOT— the folder wherecollectstaticcopies all static files for production. This folder is served by your web server, not Django.
3. Using static files in templates
Always use the {% static %} tag to reference static files in templates — never hardcode the path. This way the URL adjusts automatically if you change STATIC_URL.
{% load static %}
<link rel="stylesheet" href="{% static 'css/main.css' %}">
<script src="{% static 'js/app.js' %}"></script>
<img src="{% static 'images/logo.png' %}" alt="Logo">
The {% load static %} line must appear at the top of any template that uses the {% static %} tag. If you use template inheritance, put it in the child template too — not just in base.html.
4. collectstatic
In production, Django does not serve static files itself — your web server (Nginx, Apache) does. Before deploying, you run collectstatic to gather all static files from every app and the project-level folder into STATIC_ROOT:
python manage.py collectstatic
Django copies files from:
- Each folder listed in
STATICFILES_DIRS - The
static/subfolder inside each app inINSTALLED_APPS
All files end up in staticfiles/ at the root of myproject. Your web server then serves this folder directly.
staticfiles/ to your .gitignore — it is auto-generated and should not be committed to Git.
5. Media files settings
Add these settings to mysite/settings/base.py:
# mysite/settings/base.py
MEDIA_URL = 'media/'
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL— the URL prefix for uploaded files. For example/media/uploads/photo.jpg.MEDIA_ROOT— the folder on disk where uploaded files are saved. Django creates this folder automatically when the first file is uploaded.
6. Serving media files in development
Unlike static files, Django does not serve media files automatically in development. You need to add a URL pattern to mysite/urls.py to handle this:
# mysite/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('pages.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
The if settings.DEBUG block ensures this only applies in development. In production, your web server handles media files directly — Django never touches them.
7. Using media files in templates
When a model has a FileField or ImageField, Django stores the file path relative to MEDIA_ROOT. The field also provides a .url property that builds the full URL using MEDIA_URL:
Always use .url on file fields in templates — never build the path manually. This keeps your templates portable if you later move files to a cloud storage provider like S3.
8. Production note
In production, neither static files nor media files should be served by Django. Your web server handles both:
- Static files — served from
STATIC_ROOT(staticfiles/) by Nginx or Apache. - Media files — served from
MEDIA_ROOT(media/) by Nginx or Apache, or stored on a cloud provider like AWS S3.
9. Next steps
Static and media are configured correctly for both development and production. The last page in this section covers logging — how to set up Django's logging system so you can track errors and debug issues in both environments.