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.
STATIC_URL = "static/"You can now use the static template tag in your HTML templates to build the correct URL for any given file.
{% 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:
my_app/static/my_app/example.jpgIt 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:
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.staticfilesapp, or - you want to serve files directly from STATIC_ROOT to better imitate production behavior.
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.
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.
STATIC_ROOT = "/var/www/example.com/static/"Next, you run the collectstatic command in your terminal.
python manage.py collectstaticThis 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.
