Paramclasses Academy - Blog

Tutorials Details

Django Static Files, CSS, JavaScript, and Images: Complete Practical Guide

Django Static Files, CSS, JavaScript, and Images: Complete Practical Guide

October 19, 2026

Django Static Files, CSS, JavaScript, and Images: Complete Practical Guide

1. Introduction to Static Files in Django

A professional website needs more than Python code and HTML templates. It also needs styling, images, icons, and JavaScript interactions.

Django uses static files to manage these resources.

Static files commonly include:

  • CSS files for colors, layouts, typography, and animations.

  • JavaScript files for interactive features.

  • Images for banners, logos, and other visual content.

  • Fonts and icons used by the website.

In this module, you will learn how to configure static files, connect CSS and JavaScript to Django templates, display images, and prepare static assets for deployment.

2. Understand Django's Static and Media Files

Django applications commonly distinguish between static files and media files.

Static Files Media Files
CSS stylesheets Uploaded profile pictures
JavaScript files Uploaded documents
Website logos included with the project User-uploaded product images
Background images shipped with the website Images uploaded through forms

Static files are generally managed by developers. Media files are usually uploaded by users or administrators.

3. Create a Static Files Folder

Suppose your Django project has the following structure:

myproject/
│
├── manage.py
├── myproject/
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
│
├── accounts/
│   ├── views.py
│   └── urls.py
│
├── templates/
│   └── home.html
│
└── static/
    ├── css/
    │   └── style.css
    ├── js/
    │   └── script.js
    └── images/
        └── logo.png

Here, the project-level static directory stores CSS, JavaScript, and image assets.

You can create these folders manually in your code editor.

4. Configure Static Files in settings.py

Open the project's settings.py file.

Check that the following setting exists:

STATIC_URL = "static/"

For a project-level static directory, configure:

STATICFILES_DIRS = [
    BASE_DIR / "static",
]

If STATICFILES_DIRS already exists, update the existing setting instead of creating a duplicate.

Django's static-files app should also be enabled:

INSTALLED_APPS = [
    # Existing applications...
    "django.contrib.staticfiles",
]

A standard Django project already includes this app.

Important: STATIC_URL is the URL prefix used to reference static files. STATICFILES_DIRS tells Django where to look for additional static files during development and collection.

5. Connect CSS to a Django Template

Create the file:

static/css/style.css

Add the following CSS:

/* General page styling */
body {
    margin: 0;
    font-family: Arial, sans-serif;
    background-color: #f4f7fb;
    color: #1f2937;
}

/* Navigation bar */
.navbar {
    background-color: #172554;
    color: white;
    padding: 18px 24px;
}

/* Main content */
.container {
    max-width: 1100px;
    margin: 30px auto;
    padding: 20px;
}

/* Content card */
.card {
    background-color: white;
    padding: 24px;
    border-radius: 12px;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
}

/* Button */
.btn {
    display: inline-block;
    padding: 10px 18px;
    background-color: #2563eb;
    color: white;
    text-decoration: none;
    border-radius: 6px;
    transition: background-color 0.2s ease;
}

.btn:hover {
    background-color: #1d4ed8;
}

/* Responsive layout */
@media (max-width: 600px) {
    .container {
        margin: 15px auto;
        padding: 12px;
    }

    .card {
        padding: 16px;
    }
}

Now open your template, for example templates/home.html, and add:

{% load static %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Django Home Page</title>

    <link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>

    <nav class="navbar">
        <h2>My Django Website</h2>
    </nav>

    <main class="container">
        <section class="card">
            <h1>Welcome to Django</h1>
            <p>This page uses an external CSS file.</p>

            <a href="#" class="btn">Learn More</a>
        </section>
    </main>

</body>
</html>

The {% load static %} tag enables Django's static template tag library.

The {% static 'css/style.css' %} expression generates the URL for the CSS file using your static-files configuration.

6. Add JavaScript to Your Django Website

JavaScript makes websites interactive. It can respond to button clicks, validate user interactions, update interface elements, and perform many other tasks.

Create:

static/js/script.js

Add:

document.addEventListener("DOMContentLoaded", function () {
    const button = document.getElementById("welcomeButton");
    const message = document.getElementById("welcomeMessage");

    if (button && message) {
        button.addEventListener("click", function () {
            message.textContent =
                "JavaScript is working with Django!";
        });
    }
});

Update the content inside your template's <body>:

<section class="card">
    <h1>Welcome to Django</h1>

    <p id="welcomeMessage">
        Click the button to test JavaScript.
    </p>

    <button
        type="button"
        id="welcomeButton"
        class="btn"
    >
        Test JavaScript
    </button>
</section>

Load the JavaScript file near the end of the body:

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

Your page now uses JavaScript to update the message when the button is clicked.

For JavaScript that is not needed until the page loads, you can also place the script in the <head> and use the defer attribute.

7. Display Images in Django Templates

Place your image in:

static/images/logo.png

Use the static template tag to display it:

{% load static %}

<img
    src="{% static 'images/logo.png' %}"
    alt="Website Logo"
    width="150"
>

You can also use an image as a CSS background:

.hero {
    background-image: url("../images/banner.jpg");
    background-size: cover;
    background-position: center;
    min-height: 300px;
}

The relative URL above works because the CSS file is located in static/css/ and the image is located in static/images/.

For production deployments, ensure that the static files are collected and served correctly.

8. Reuse CSS and JavaScript with Template Inheritance

As your website grows, you should avoid repeating the same HTML structure in every page.

Create a base template:

templates/base.html

{% load static %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>{% block title %}My Django Website{% endblock %}</title>

    <link rel="stylesheet" href="{% static 'css/style.css' %}">

    {% block extra_css %}{% endblock %}
</head>
<body>

    <nav class="navbar">
        <h2>My Django Website</h2>
    </nav>

    <main class="container">
        {% block content %}{% endblock %}
    </main>

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

    {% block extra_js %}{% endblock %}
</body>
</html>

Now create a child template:

templates/home.html

{% extends "base.html" %}

{% block title %}Home | My Django Website{% endblock %}

{% block content %}
    <section class="card">
        <h1>Welcome to Django</h1>
        <p>This page inherits its layout and assets from base.html.</p>
    </section>
{% endblock %}

This approach keeps your design consistent across multiple pages. If you update the navigation bar or global stylesheet, the changes can apply to all templates that extend the base template.

9. Static Files Inside an Individual App

Django also supports static files stored inside individual applications.

For example:

accounts/
├── static/
│   └── accounts/
│       ├── css/
│       │   └── login.css
│       └── images/
│           └── profile-placeholder.png
├── templates/
│   └── accounts/
│       └── login.html
└── views.py

In login.html, load the file like this:

{% load static %}

<link
    rel="stylesheet"
    href="{% static 'accounts/css/login.css' %}"
>

Namespacing files inside an app directory, such as accounts/css/login.css, helps avoid filename conflicts between different apps.

10. Configure User-Uploaded Media Files

Media files are different from static assets. For example, a student may upload a profile photograph through a form.

In settings.py, add:

MEDIA_URL = "media/"
MEDIA_ROOT = BASE_DIR / "media"

A model can store an uploaded image using ImageField:

from django.db import models

class StudentProfile(models.Model):
    name = models.CharField(max_length=100)
    profile_image = models.ImageField(
        upload_to="student_profiles/",
        blank=True,
        null=True
    )

Install Pillow if required for image-field support:

python -m pip install Pillow

After creating or changing the model, run:

python manage.py makemigrations
python manage.py migrate

For local development, you can configure media URL serving in the main project's urls.py:

from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    path("accounts/", include("accounts.urls")),
]

if settings.DEBUG:
    urlpatterns += static(
        settings.MEDIA_URL,
        document_root=settings.MEDIA_ROOT
    )

This is a development convenience, not a production media-serving solution.

In production, configure a suitable web server or storage service for uploaded media. Validate uploads and restrict access to private files where necessary.

11. Collect Static Files for Production

When deploying a Django website, the development server should not be relied on to serve static files in production.

Configure a collection directory in settings.py:

STATIC_ROOT = BASE_DIR / "staticfiles"

Keep the existing STATIC_URL and any required STATICFILES_DIRS settings.

Run:

python manage.py collectstatic

Django collects the static assets it discovers into the directory specified by STATIC_ROOT.

Your production environment must then serve that directory through a correctly configured web server, hosting platform, or static-file storage service.

Remember: STATICFILES_DIRS identifies additional source directories. STATIC_ROOT identifies the destination used by collectstatic. They serve different purposes and should not point to the same directory.

12. Troubleshooting Common Static File Errors

Error 1: CSS is not working

Check the following:

  • {% load static %} appears in the template.

  • The CSS path matches the actual file location.

  • STATIC_URL and STATICFILES_DIRS are configured correctly.

  • The template uses {% static 'css/style.css' %}.

  • Browser caching is not showing an older stylesheet.

You can use browser developer tools to inspect the Network tab and check whether the CSS request returns a successful response.

Error 2: Image returns 404

Verify the image's exact filename, extension, capitalization, and folder location. Also check the generated URL.

Error 3: JavaScript does not run

Check the browser console for errors. Confirm that the JavaScript file loads and that the element IDs used in the code match those in the HTML.

Error 4: Static files work locally but not after deployment

Check that collectstatic has been run, that the production static-file server is configured, and that the generated asset URLs are correct.

Error 5: ImproperlyConfigured or invalid static settings

Check for duplicate or conflicting settings. Confirm that STATIC_ROOT and STATICFILES_DIRS have the intended separate roles.

13. Frequently Asked Questions

Q1. What are static files in Django?

Static files include CSS, JavaScript, and website assets such as logos and images.

Q2. What does {% load static %} do?

It loads Django's static template tag library so you can generate static asset URLs.

Q3. What is STATIC_URL?

It defines the URL prefix used to reference static files.

Q4. What is STATICFILES_DIRS?

It specifies additional directories where Django searches for static files.

Q5. What is STATIC_ROOT?

It defines the destination directory for files collected by collectstatic.

Q6. What does collectstatic do?

It gathers static files from the configured locations into the collection destination for deployment.

Q7. What is the difference between static files and media files?

Static files are usually project assets, while media files are typically uploaded through the application.

Q8. Can Django templates use JavaScript?

Yes. Templates can include JavaScript directly or reference external JavaScript files using the static template tag.

Q9. Why use a base template?

A base template allows multiple pages to reuse a common layout, stylesheets, and scripts.

Q10. Should Django's development server serve static files in production?

No. Production static files should be served using an appropriate production-ready configuration.

14. Interview Questions and Answers

Q1. Explain Django's static-file system.

Django's static-file system helps developers discover, reference, and collect assets such as CSS, JavaScript, and images.

Q2. Explain STATIC_URL, STATICFILES_DIRS, and STATIC_ROOT.

STATIC_URL defines the asset URL prefix, STATICFILES_DIRS identifies additional source directories, and STATIC_ROOT defines the collection destination.

Q3. Why is {% load static %} required?

It makes the static template tags available in a template.

Q4. What is the purpose of collectstatic?

It collects static assets into a central destination so they can be served by the production environment.

Q5. What is the difference between MEDIA_ROOT and MEDIA_URL?

MEDIA_ROOT is the filesystem location for uploaded media. MEDIA_URL is the URL prefix used to access that media.

Q6. How can templates share a common design?

Use template inheritance with {% extends %} and named blocks.

Q7. Why should uploaded files be validated?

Validation helps reduce security risks, unexpected file types, and application errors.

15. Practical Assignment

Create a professional homepage for your Student Management System.

Requirements:

  1. Create a project-level static directory.

  2. Add a CSS stylesheet and apply a consistent color scheme.

  3. Add a JavaScript file with a working button interaction.

  4. Display a logo and a banner image.

  5. Create a base.html template.

  6. Use template inheritance for the homepage.

  7. Create a responsive layout for desktop and mobile.

  8. Configure a media directory for student profile uploads.

  9. Test static asset paths using browser developer tools.

  10. Run collectstatic and verify that the production configuration is ready.

Bonus task: Build a responsive student dashboard with navigation, statistic cards, and a profile section.

16. Conclusion

Django's static-file system makes it possible to organize and serve CSS, JavaScript, and website images correctly. Understanding static files, media files, template inheritance, and collectstatic is essential when building professional Django applications.

Practice the examples, verify every asset path, and test the layout at different screen sizes before moving to the next module.

Next Module: Django Admin Panel Customization — Managing Models, List Displays, Search, Filters, and Admin Actions.