Django Static Files

Your website needs more than just HTML — it needs CSS to look good, JavaScript for interactivity, and images for visuals. In Django, these files (CSS, JS, images) are called Static Files. This lesson covers how to organize, configure, and use static files correctly in a Django project.

What are Static Files?

Static files are files that do not change for each user — they are the same for everyone who visits the website. These include:

  • CSS files — Style your pages (fonts, colors, layouts)
  • JavaScript files — Add interactivity (buttons, popups, sliders)
  • Images — Logos, banners, icons, backgrounds
  • Fonts — Custom typefaces used on the website
Example: Think of a restaurant. The food on the menu changes daily (dynamic content). But the restaurant's signboard, furniture, and decoration remain the same for every customer (static files). CSS, JS, and images are that furniture and decoration — they don't change based on who is visiting.

Static Files vs Media Files

It's important to understand the difference between the two types of non-HTML files in Django:

  • Static files: Files created by the developer — CSS, JS, design images. These are placed in the project manually by you.
  • Media files: Files uploaded by users — profile photos, documents, attachments. These are stored dynamically when users submit forms with file uploads.

This lesson focuses on static files. Media files are handled differently (covered in a separate lesson).

Setting Up the Static Files Folder

Create a static folder inside your app directory. Inside it, create subfolders to keep things organized:


students/
└── static/
    └── students/
        ├── css/
        │   └── style.css
        ├── js/
        │   └── script.js
        └── images/
            └── logo.png

The inner folder with the app name (e.g., static/students/) is a Django best practice. It prevents filename conflicts when multiple apps have files with the same name.

Configuring Static Files in settings.py

Django's static file settings are already partially configured by default. Open settings.py and make sure django.contrib.staticfiles is in INSTALLED_APPS (it is, by default):


INSTALLED_APPS = [
    ...
    'django.contrib.staticfiles',    # <-- Make sure this is present
    ...
]

Also confirm the STATIC_URL setting exists (it does by default):


STATIC_URL = '/static/'

This tells Django that all static files will be served from the /static/ URL path in the browser.

STATICFILES_DIRS — For Project-Level Static Folder

If you want a shared static folder at the project root level (not inside any one app), add this setting:


STATICFILES_DIRS = [
    BASE_DIR / 'static',    # Project-level static folder
]

Your project folder structure would then look like:


myschool/
├── static/              <-- Project-level shared static files
│   ├── css/
│   │   └── main.css
│   └── images/
│       └── school-logo.png
├── manage.py
└── myschool/

Loading Static Files in a Template

To use static files in your HTML templates, you must load the {% load static %} tag at the top of the template, then use {% static 'path' %} to generate the correct URL for each file.


<!DOCTYPE html>
<html>
<head>
    {% load static %}
    <title>My School</title>
    <link rel="stylesheet" href="{% static 'students/css/style.css' %}">
</head>
<body>
    <img src="{% static 'students/images/logo.png' %}" alt="School Logo">

    <h1>Welcome to My School</h1>

    <script src="{% static 'students/js/script.js' %}"></script>
</body>
</html>
Example: {% static 'students/css/style.css' %} is like giving Django the file's nickname and asking it: "Give me the full address of this file." Django converts it to the correct full URL like /static/students/css/style.css automatically. If you ever move the static folder, Django handles the path change — your template code stays the same.

Why Use {% static %} Instead of Hardcoding the Path?

You might wonder — why not just write href="/static/students/css/style.css" directly? The reason is flexibility. The {% static %} tag uses the STATIC_URL from settings.py. If you ever change the static files location (e.g., move to a CDN in production), you only update it in settings.py and all your templates update automatically.

Adding Static Files to the Base Template

In a real project, you load CSS and JS in your base template so all child templates inherit them automatically. Put {% load static %} at the very top:


{% load static %}
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}My School{% endblock %}</title>
    <link rel="stylesheet" href="{% static 'css/main.css' %}">
</head>
<body>
    {% block content %}{% endblock %}

    <script src="{% static 'js/script.js' %}"></script>
</body>
</html>

Every child template that extends this base will automatically get the CSS and JavaScript without loading them again.

Adding an Extra Static Block for Page-Specific Files

Sometimes a specific page needs its own additional CSS or JS. Add an extra block in your base template for this:


<!-- In base.html -->
    <link rel="stylesheet" href="{% static 'css/main.css' %}">
    {% block extra_css %}{% endblock %}   <-- Child pages can add more CSS here

<!-- In a child template -->
{% extends 'base.html' %}

{% block extra_css %}
    <link rel="stylesheet" href="{% static 'css/gallery.css' %}">
{% endblock %}

STATIC_ROOT — For Production Deployment

During development, Django serves static files automatically. But when you deploy your project to a live server, Django does not serve static files on its own — a web server like Nginx or a CDN does. Django's collectstatic command gathers all static files from all apps into one single folder:


# settings.py
STATIC_ROOT = BASE_DIR / 'staticfiles'    # Where collected files will go

# Then run this command before deployment:
python manage.py collectstatic
Example: collectstatic is like a packing team before a product launch. Each team member (app) has their own box of materials (static files). Before the big event (deployment), the packing team collects all boxes and organizes them into one single shipment (the staticfiles folder) ready to be sent out.

Quick Recap

  • Static files are CSS, JavaScript, and images — they are the same for all users.
  • Create a static/appname/ folder inside your app to organize static files.
  • Add STATIC_URL = '/static/' in settings.py (it's already there by default).
  • Always use {% load static %} at the top of any template that uses static files.
  • Use {% static 'path/to/file' %} instead of hardcoding the file path.
  • Use STATICFILES_DIRS to add a project-level shared static folder.
  • Run python manage.py collectstatic before deploying to a live server.

Leave a Comment

Your email address will not be published. Required fields are marked *