Skip to content

Chapter 11: Static and Media Files ​

11.1 Static File Management ​

STATIC_URL Configuration ​

Static files include CSS, JavaScript, images and other files that don't change frequently. Django provides a complete static file management mechanism.

Basic configuration:

python
# settings.py
import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

# Static file URL prefix
STATIC_URL = '/static/'

# Static file directories in development environment
STATICFILES_DIRS = [
    BASE_DIR / "static",
    BASE_DIR / "assets",
]

# Static file collection directory in production environment
STATIC_ROOT = BASE_DIR / "staticfiles"

# Static file finders
STATICFILES_FINDERS = [
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]

App-level static file organization:

myapp/
    static/
        myapp/
            css/
                style.css
                responsive.css
            js/
                main.js
                utils.js
            images/
                logo.png
                favicon.ico

Using static files in templates:

html
{% load static %}

<!DOCTYPE html>
<html>
<head>
    <title>My Website</title>
    <!-- CSS files -->
    <link rel="stylesheet" type="text/css" href="{% static 'myapp/css/style.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'myapp/css/responsive.css' %}">
</head>
<body>
    <!-- Image -->
    <img src="{% static 'myapp/images/logo.png' %}" alt="Logo">
    
    <!-- JavaScript files -->
    <script src="{% static 'myapp/js/main.js' %}"></script>
</body>
</html>

collectstatic Command ​

In production environments, use the collectstatic command to collect all static files to the STATIC_ROOT directory:

bash
# Collect all static files
python manage.py collectstatic

# Force collection (overwrite existing files)
python manage.py collectstatic --noinput --clear

# Collect static files for specific apps only
python manage.py collectstatic --noinput --verbosity=2

# Show files to be collected without actually executing
python manage.py collectstatic --dry-run

Customize collectstatic behavior:

python
# management/commands/custom_collectstatic.py
from django.contrib.staticfiles.management.commands.collectstatic import Command as CollectStaticCommand
from django.contrib.staticfiles.storage import staticfiles_storage
import os

class Command(CollectStaticCommand):
    def collect(self):
        # Execute custom logic before collection
        self.stdout.write("Starting to collect static files...")
        
        # Call parent method
        collected = super().collect()
        
        # Execute custom logic after collection
        self.stdout.write("Static file collection completed!")
        
        return collected

CSS/JS File Organization ​

Recommended static file organization structure:

static/
    css/
        base.css
        components/
            buttons.css
            forms.css
            navigation.css
        pages/
            home.css
            blog.css
        vendor/
            bootstrap.min.css
            fontawesome.css
    js/
        base.js
        components/
            modal.js
            dropdown.js
        pages/
            blog.js
        vendor/
            jquery.min.js
            bootstrap.bundle.min.js
    images/
        logos/
            main-logo.png
            favicon.ico
        icons/
            search.svg
            menu.svg
    fonts/
        custom-font.woff2
    scss/
        base.scss
        components/
            _buttons.scss
        main.scss

Handling SCSS files in Django:

python
# settings.py
# Install django-sass-processor
# pip install django-sass-processor

INSTALLED_APPS = [
    # ...
    'sass_processor',
]

STATICFILES_FINDERS = [
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'sass_processor.finders.CssFinder',
]

SASS_PROCESSOR_ENABLED = True
SASS_PROCESSOR_ROOT = BASE_DIR / 'static'
scss
// static/scss/main.scss
$primary-color: #007bff;
$secondary-color: #6c757d;

@import "components/buttons";
@import "components/forms";

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
}

.header {
    background-color: $primary-color;
    color: white;
    padding: 1rem;
}

Development vs Production Environment ​

Static file configuration in different environments:

python
# settings/base.py
import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent.parent

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    BASE_DIR / "static",
]

# settings/development.py
from .base import *

DEBUG = True

# Provide static files directly from source directories in development
STATICFILES_DIRS = [
    BASE_DIR / "static",
    BASE_DIR / "assets",
]

# settings/production.py
from .base import *

DEBUG = False

# Provide static files from collection directory in production
STATIC_ROOT = BASE_DIR / "staticfiles"

# Enable static file compression
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'

# Configuration when using CDN
# STATIC_URL = 'https://cdn.example.com/static/'

Optimizing static files in production environment:

python
# settings/production.py
# Static file cache control
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'

# Compress static files
# Install django-compressor
# pip install django-compressor

INSTALLED_APPS = [
    # ...
    'compressor',
]

MIDDLEWARE = [
    # ...
    'compressor.middleware.CompressorMiddleware',
]

COMPRESS_ENABLED = True
COMPRESS_OFFLINE = True  # Offline compression
COMPRESS_CSS_FILTERS = [
    'compressor.filters.css_default.CssAbsoluteFilter',
    'compressor.filters.cssmin.rCSSMinFilter',
]
COMPRESS_JS_FILTERS = [
    'compressor.filters.jsmin.JSMinFilter',
]

Static file compression in templates:

html
{% load static %}
{% load compress %}

<!DOCTYPE html>
<html>
<head>
    <title>My Website</title>
    
    {% compress css %}
    <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/components/buttons.css' %}">
    <link rel="stylesheet" type="text/x-scss" href="{% static 'scss/main.scss' %}">
    {% endcompress %}
</head>
<body>
    <!-- Page content -->
    
    {% compress js %}
    <script src="{% static 'js/vendor/jquery.min.js' %}"></script>
    <script src="{% static 'js/base.js' %}"></script>
    <script src="{% static 'js/components/modal.js' %}"></script>
    {% endcompress %}
</body>
</html>

With these configurations, you can effectively manage static files in Django projects, ensuring static resources are correctly provided in both development and production environments.

Summary ​

Django static file management provides a complete solution:

  1. ✅ STATIC_URL configuration defines static file access paths
  2. ✅ collectstatic command collects all static resources
  3. ✅ Reasonable file organization structure improves maintainability
  4. ✅ Differentiated configuration for development and production environments
  5. ✅ Static file compression optimizes performance

Proper static file management is an important part of web application performance optimization.

Next Article ​

We will learn about media file handling.

11.2 Media File Handling →

Directory ​

Return to Course Directory

Released under the [BY-NC-ND License](https://creativecommons.org/licenses/by-nc-nd/4.0/deed.en).