Skip to content

Static and Media Files

Websites typically need to serve additional assets such as images, JavaScript and CSS. Django refers to these as static files and provides the django.contrib.staticfiles app to help you manage them efficiently.

Configuring Static Files

First, make sure that django.contrib.staticfiles is included in your INSTALLED_APPS list. Next, define the STATIC_URL in your settings file to specify the base URL for these files.

python
STATIC_URL = "static/"

You can now use the static template tag in your HTML templates to build the correct URL for any given file.

html
{% load static %}
<img src="{% static 'my_app/example.jpg' %}" alt="My image">

Organizing Static Files

You should store your static files in a folder called static within your app directory. For example:

shell
my_app/static/my_app/example.jpg

It is strongly recommended to namespace your files by putting them inside an extra subdirectory named after your app. This prevents Django from getting confused if two different apps happen to have a static file with the exact same name.

Global Static Files

If you have project-level static assets that do not belong to a specific app, you can tell Django where to find them by defining the STATICFILES_DIRS setting:

python
STATICFILES_DIRS = [
    BASE_DIR / "static",
    # Optional additional paths
    # "/var/www/static/",
]

Serving Static Files During Development

When you use django.contrib.staticfiles and have DEBUG = True in your settings, the built-in runserver command will automatically discover and serve static files from:

  • Each app’s static/ directory.
  • Any directories listed in STATICFILES_DIRS.

This automatic method is inefficient and insecure. It is only meant for local development and should never be used in a live production environment.

However, runserver does not serve files from STATIC_ROOT directory, which is intended for production use and is populated by the collectstatic command. Django provides a helper function (static()) for this purpose and it can be used when:

  • you are not using the django.contrib.staticfiles app, or
  • you want to serve files directly from STATIC_ROOT to better imitate production behavior.
python
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # your normal URL patterns…
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

NOTE

This helper function only works when DEBUG = True and only for local URL prefixes such as /static/ or /media/. It is intended for development use only and is not suitable for production.

Serving User-Uploaded Media Files During Development

You can use the exact same helper function to serve user-uploaded media files from your MEDIA_ROOT folder while developing locally. Once again, this is not suitable for production use.

python
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URL configuration ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Testing

When you write tests that rely on actual HTTP requests, your static assets need to load correctly so the test environment accurately reflects reality. The standard testing client assumes static files have already been collected into your STATIC_ROOT folder.

To avoid running the collection command before every single test, Django provides a special StaticLiveServerTestCase class. This class transparently serves all your static assets during test execution exactly like the development server does.

Deployment

Django provides a management command to gather all your static files into a single directory so they are ready for deployment.

First, you set the STATIC_ROOT variable in your settings file. This defines the absolute path on your server where you want the files to be collected.

python
STATIC_ROOT = "/var/www/example.com/static/"

Next, you run the collectstatic command in your terminal.

bash
python manage.py collectstatic

This command safely copies every static file from your various app folders and global directories (defined in STATICFILES_DIRS) into the designated STATIC_ROOT directory. Your web server (Nginx, Apache, CDN etc.) should then be configured to serve files directly from this directory. This topic is further discussed later in this book.