Websites are not made of HTML alone. To create attractive and interactive pages, you also need CSS, JavaScript, and images. In Django, these files are called static files.
In this tutorial, you will learn what static files are, why they are important, how Django handles them, how to configure them correctly, and how to use CSS, JavaScript, and images in your templates.
Static files are files that do not change dynamically for each request. They are usually served as they are.
Common examples of static files are:
A stylesheet like:
body {
background-color: #f5f5f5;
}is a static file because Django does not generate it each time from database logic. It is simply loaded and sent to the browser.
Static files are essential because they improve both the appearance and the functionality of your website.
Used for styling:
Used for interactivity:
Used for visual content:
Without static files, your Django site would look very plain and limited.
Beginners often confuse these two concepts.
These are files used by the website itself.
Examples:
These are files uploaded by users or administrators.
Examples:
In this tutorial, we focus only on static files.
Django provides a built-in system for handling static files during development.
To use static files correctly, Django needs:
STATIC_URL{% load static %} template tagThese work together so templates can find and display CSS, JavaScript, and images.
Open your settings.py file and check for this line:
STATIC_URL = 'static/'This tells Django that static files will be accessed through URLs starting with:
/static/For example:
/static/css/style.cssThis is the public URL path, not necessarily the actual folder path.
A common way to organize static files inside an app is like this:
blog/
├── static/
│ └── blog/
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── script.js
│ └── images/
│ └── logo.pngblog/ inside static/?Because different apps may have files with the same name.
For example:
blog/static/blog/style.cssshop/static/shop/style.cssThis avoids name conflicts.
Let us create a CSS file:
blog/static/blog/css/style.cssExample content:
body {
background-color: #f0f8ff;
font-family: Arial, sans-serif;
}
h1 {
color: darkblue;
}This file will style your template.
Before using static files in a Django template, you must load the static template tag library.
At the top of your HTML template, add:
{% load static %}Then link your CSS file like this:
<link rel="stylesheet" href="{% static 'blog/css/style.css' %}">{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>My Blog</title>
<link rel="stylesheet" href="{% static 'blog/css/style.css' %}">
</head>
<body>
<h1>Welcome to my blog</h1>
</body>
</html>Now your CSS file is correctly connected.
You can also add JavaScript files in the same way.
blog/static/blog/js/script.jsconsole.log("JavaScript is working!");<script src="{% static 'blog/js/script.js' %}"></script>{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>My Blog</title>
</head>
<body>
<h1>Welcome</h1>
<script src="{% static 'blog/js/script.js' %}"></script>
</body>
</html>
This allows you to add behavior and interactivity.
Images can also be stored as static files.
blog/static/blog/images/logo.png<img src="{% static 'blog/images/logo.png' %}" alt="Logo">{% load static %}
<img src="{% static 'blog/images/logo.png' %}" alt="My Blog Logo">This is useful for logos, icons, banners, and decorative images.
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>Blog Home</title>
<link rel="stylesheet" href="{% static 'blog/css/style.css' %}">
</head>
<body>
<img src="{% static 'blog/images/logo.png' %}" alt="Logo" width="100">
<h1>Welcome to My Blog</h1>
<p>This page uses static CSS and images.</p>
<script src="{% static 'blog/js/script.js' %}"></script>
</body>
</html>This simple example combines HTML, CSS, JavaScript, and an image.
There are two common ways to organize static files.
Example:
blog/static/blog/css/style.cssThis is very common and clean for reusable apps.
Example:
project_root/
├── static/
│ ├── css/
│ ├── js/
│ └── images/This is often used for project-wide assets shared by many apps.
If you want a shared static folder at the project level, add this to settings.py:
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_URL = 'static/'
STATICFILES_DIRS = [
BASE_DIR / 'static',
]It tells Django to also search for static files in the project-level static/ folder.
This is useful for:
Suppose you have:
project_root/
├── static/
│ └── css/
│ └── main.cssThen in your template:
{% load static %}
<link rel="stylesheet" href="{% static 'css/main.css' %}">This works because Django now knows about the global static folder.
When DEBUG = True, Django can serve static files automatically during development.
This means if your project is running locally with:
python manage.py runserverDjango will handle your static files for you.
This is convenient for learning and testing.
In production, static files are usually handled differently.
Django does not usually serve static files directly in a production setup. Instead, they are often served by:
To prepare static files for production, Django uses:
python manage.py collectstaticThis collects static assets into a single directory for deployment.
For now, it is enough to understand that:
You will learn this more deeply in deployment tutorials.
collectstatic?collectstatic is a Django management command that gathers all static files from apps and project folders into one destination directory.
This is useful in production.
Typical production setting:
STATIC_ROOT = BASE_DIR / 'staticfiles'Then run:
python manage.py collectstaticThis copies static files into the staticfiles/ directory.
{% load static %}If you do not load the static tag library, this will not work:
{% static 'blog/css/style.css' %}If the path is incorrect, Django will not find the file.
Example:
{% static 'css/style.css' %}when the actual file is:
blog/static/blog/css/style.cssThe correct path is:
{% static 'blog/css/style.css' %}Files should be stored in a recognized static directory.
A logo you created for the site is static.
A profile picture uploaded by a user is media.
Sometimes CSS changes do not appear immediately because the browser caches static files.
A clean example:
static/
├── css/
│ └── main.css
├── js/
│ └── app.js
└── images/
└── logo.pngAnd for app-specific assets:
blog/static/blog/css/post.cssThis makes projects easier to maintain.
blog/static/blog/css/style.cssbody {
background-color: #eef2f7;
font-family: Arial, sans-serif;
}
h1 {
color: #1e3a8a;
text-align: center;
}
p {
color: #333;
}
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>Blog Home</title>
<link rel="stylesheet" href="{% static 'blog/css/style.css' %}">
</head>
<body>
<h1>Welcome to My Blog</h1>
<p>This page is styled with a static CSS file.</p>
</body>
</html>
When you run the server and open the page, the design will look much better.
Think of your Django template as a house.
Without static files, the house exists, but it does not feel complete.
In this tutorial, you learned what static files are and why they are important in Django. You saw how to create static folders, add CSS, JavaScript, and images, and load them into templates using {% load static %} and the {% static %} tag. You also learned the difference between app-level and project-level static files, and got a first introduction to collectstatic for production.
This is a key step in making your Django websites look professional and interactive.
STATIC_URL defines the public path for static files{% load static %} must be used in templates{% static 'path/to/file' %} generates file URLsSTATICFILES_DIRS can add a global static foldercollectstatic prepares static files for production{% load static %} in templates?collectstatic do?Static files are what transform a simple Django page into a real website with design and interactivity. Once you understand how static files work, you can begin building pages that are not only functional, but also attractive and user-friendly.