Handling static files in Django: configuration, examples, and best practices
Content Index
- 1. What are static files in Django and what are they used for?
- 2. Initial Configuration: enabling static files in settings.py
- Difference between development and production
- 3. Folder structure and good organization practices
- 4. How to integrate Bootstrap and Font Awesome into your Django project
- Another option: Use CDNs (faster and simpler)
- 5. Serving static files in production: WhiteNoise and collectstatic
- 6. Common errors and how to solve them
- 7. Conclusions: what I learned from handling static files in Django
- Frequently Asked Questions (FAQ)
Once we have our files loaded, the next thing on the list is to display them with style. For this, we must learn to handle CSS, JavaScript, and other files.
When I configured my first Django project, the hardest thing for me to understand was how the framework managed CSS, JavaScript, and image files. After several attempts and errors, I understood that the correct handling of static files is the key for a web application to have style, interaction, and good organization.
In this guide, I show you how to configure, organize, and serve static files in Django, in addition to integrating external libraries like Bootstrap and Font Awesome without complications.
1. What are static files in Django and what are they used for?
Static files are resources that do not change over time: stylesheets (CSS), scripts (JS), images, icons, fonts, etc.
Django has an integrated system to manage them in an organized way, both in development and production.
When I set up my environment, I discovered that Django does not automatically serve these files outside of development mode. That's why it's essential to understand how to tell the framework where to find them and how to distribute them.
2. Initial Configuration: enabling static files in settings.py
The first step to handle static files is to edit your project's settings.py file.
There you must include the following basic configuration:
STATIC_URL = 'static/'In my case, with that single line, Django already recognized the static folder in each application.
However, for larger projects or when moving to production, it is necessary to define two more variables:
STATICFILES_DIRS = [BASE_DIR / "static"] STATIC_ROOT = BASE_DIR / "staticfiles"- STATICFILES_DIRS: tells Django where to look for additional static files.
- STATIC_ROOT: defines the folder where Django collects all files when you run collectstatic.
Difference between development and production
In development, Django serves the files directly from the static folders.
In production, you must run:
$ python manage.py collectstaticThis command copies all files to the STATIC_ROOT folder, ready to be served by a web server or a library like WhiteNoise.
To be able to use static files in the project, we configure the following variable:
customlogin\customlogin\settings.py
STATIC_URL = "static/"More information at:
https://docs.djangoproject.com/en/dev/howto/static-files/
3. Folder structure and good organization practices
One of the things that helped me the most to keep things organized was structuring the static folders within each application.
For example:
project/
│
├── customlogin/
│ └── settings.py
│
├── account/
│ └── static/
│ └── bootstrap/
│
├── elements/
│ └── static/
│ └── fontawesome/
In my project, I had paths like account/static/ and elements/static/, which allowed me to separate styles and scripts by module or app.
Practical tips:
- Use consistent names (for example, static/css, static/js, static/img).
- Avoid duplicating CSS or JS files between apps.
- Centralize your external libraries in a common folder (static/lib/).
4. How to integrate Bootstrap and Font Awesome into your Django project
In this section, we will mainly want to customize some templates and learn about their behavior; one of the keys to this personalization is that it has a good design, and that is why we will use Bootstrap again.
Let's start by installing Bootstrap; since CodeIgniter is a framework with no link to Node, we must use the Bootstrap CDNs which we can get from the official page:
Click on "Download" and then again on "Download" in the next section:
Bootstrap, being a client-side web framework, uses CSS and JavaScript to use any Bootstrap component or functionality; once the previous compressed file is downloaded and the folder is generated (which, to simplify the process, we rename as **bootstrap**), we need the following files:
account/static/
Which we will copy inside the project's **static** folder:
- bootstrap/css/bootstrap.min.css
- bootstrap/js/bootstrap.min.js
We also install the popper dependencies which you can get from the same Bootstrap page; we install Fontawesome for the iconography:
Remember to download the free web font files from:
With Fontawesome we have access to multiple ready-to-use SVG icons.
There is also a specific package for Django in case you prefer to configure it that way:
https://fontawesome.com/docs/web/use-with/python-django
We configure in the Django master template:
proyect\app\templates\base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% load static %}
{% block head %}
<link rel="stylesheet" href="url('{% static 'bootstrap/css/bootstrap.min.css' %}'">
<title>{% block title %} Admin {% endblock %}</title>
{% endblock %}
</head>
<body>
{% block content %}
{% endblock %}
{% block footer %}
Admin - <a href="#">Contact</a>
{% endblock %}
<script src="url('{% static 'bootstrap/js/bootstrap.min.js' %}'"></script>
</body>
</html>And that's it, with this, we can now use Bootstrap 5 in a Django application; you can try other Bootstrap components, such as creating a container:
proyect\app\templates\base.html
<div class="container">
{% block content %}
{% endblock %}
</div>Very useful to prevent all content from appearing stretched, following the following rules:
From your developer console tool, you can see this option that looks like a phone with a computer behind it.
- Here we can see the client size, which would be the screen resolution.
- This is the browser.
- And this is the container, that is, the size of our content's container.
For example:
- If the client's screen is 1500 px, which is greater than 1400 px, as the console indicates, the container will have a maximum size of 1320 px.
- This is defined by media queries in CSS, where you can see that the maximum size of the container is limited to 1320 px.
When the screen is smaller than 1400 px, the container size will adjust to 1100 px, and so on for the other resolution ranges.
If we reduce the screen a bit, you will see that when passing 1400 px, the container automatically shrinks. This is achieved using another media query, as you can see in the CSS code.
With this, we correctly define the container size for our content, ensuring that it adapts responsively to different screen resolutions.
You have several types:
- container-sm
- container-lg
- container
Another option: Use CDNs (faster and simpler)
Visit getbootstrap.com and fontawesome.com to copy the links.
You paste the inside the block of your base template and that's it.
5. Serving static files in production: WhiteNoise and collectstatic
When I migrated my project to the production environment, I had to learn how to serve the files without relying on an external server.
WhiteNoise: the simple solution
Add WhiteNoise in settings.py:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
...
]Then run:
$ python manage.py collectstaticWith that, Django collects all the files and WhiteNoise takes care of serving them efficiently.
Quick Comparison
Environment Key Configuration Served by
Development STATICFILES_DIRS Django
Production STATIC_ROOT + WhiteNoise Server or middleware
6. Common errors and how to solve them
During my first tests, I made typical mistakes like these:
Error Cause Solution
Files that don't load Missing {% load static %} in the template Add {% load static %} at the beginning
404 in production You didn't run collectstatic Run python manage.py collectstatic
CSS not applied Incorrectly defined or duplicated paths Check folder structure and names
Slow loading Heavy files or lack of compression Use WhiteNoise + GZIP compression
7. Conclusions: what I learned from handling static files in Django
After working several times with this system, I understood that the secret is to maintain organization and understand the relationship between the STATIC_URL, STATICFILES_DIRS, and STATIC_ROOT variables.
Mastering static files in Django not only improves the appearance of your applications but also their performance and maintainability.
In my experience, integrating Bootstrap and Font Awesome was the step that converted a simple functional project into a visually professional application.
Frequently Asked Questions (FAQ)
What is the difference between STATIC_URL and STATIC_ROOT?
STATIC_URL defines the public access path to the files.
STATIC_ROOT indicates where all files are collected for production.
Where should CSS and JS files be saved?
Inside the static folder of each application or in a global folder defined in STATICFILES_DIRS.
How to use Bootstrap and Font Awesome in Django?
You can use CDNs or download the local files and reference them with {% static %}.
Why don't my static files show up in production?
You probably didn't run collectstatic or WhiteNoise is not configured.
How to use WhiteNoise on a server without Nginx?
Simply add it to the middleware and Django will take care of serving the files.
I agree to receive announcements of interest about this Blog.
Learn how to set up and serve static files in Django step by step. Includes real-world examples, integration with Bootstrap and Font Awesome, CSS, JavaScript, images, and solutions to common errors.