A web page also contains static assets like CSS, JavaScript, and images. And Django provides a specific configuration and storage pattern for such files. Django comes with an inbuilt app “staticfiles” that manage all the static files for the project. To distinct the static files, Django also provides a special configuration to handle staticfiles for development and deployment purposes. In this article, we will discuss how to deal with static files in Django, and learn how to serve static files in a project with debug mode True and False.
Create Django Project
So let’s get started with creating a Django project To create a Django project we use the
django-admin startproject <project_name>
command.
django-admin startproject static_tutorial
The above command will create a Django project with the name
static_tutorial,
if Django is installed for your python environment.
static_tutorial ????manage.py ????db.sqlite3 ? ????static_tutorial asgi.py settings.py urls.py wsgi.py __init__.py
It’s time to change the directory to static_tutorial project and run the local server.
python manage.py runserver
After running the local server open localhost:8000 on the browser, and you will see the default app page of Django.
Handling Static files in Django
Django provides a specific setting to manage and handle static files. And to manage all static files we need to configure the settings.py file.
Step 1: Configure Static URL
The first thing we need to configure is defining the
STATIC_URL
path for the static files in
static_tutorial/setting.py
file. The
STATIC_URL
is reserved identifiers in the Django
setting.py
file that defines the URL path for all the static files present in the project.
# static_tutorial/setting.py STATIC_URL = '/static/'
Note 1 : The name static is arbitrary it could be anything, but the name must include ‘
/
’ at the end of the name. Note 2: In your Django project the STATIC_URL will come predefined, you can change the value to any arbitrary name if you want, but we suggest you leave it as it is.
Step 2: Configure STATICFILES_DIRS
The
STATICFILES_DIRS
is also a reserved identifier, that represents a list of static files folders or directories located in the local development environment. A project can have multiple apps and each app can have its own static file directory, that's why we define an identifer
STATICFILES_DIRS
that contain the path for all the static files present in the project. For our project, we are defining a single static file directory in the top level of our project with the name
static
, that's why we will only define a single path in the STAITCFILES_DIRS list.
#static_tutorial/settings.py STATIC_URL = '/static/' STATICFILES_DIRS = [BASE_DIR / 'static', ] #new
Step 3: Configure STATIC_ROOT
STATIC_ROOT identifier is for the production level. It defines a directory that will collect all the static files when the project when the
collectstatic
command is executed. In STATIC_ROOT we define a directory path that will contain all the static files during deployment. With
STATIC_ROOT
, we distinct the static files of deployment level to deployment level. As the STATIC_ROOT define the location of static files for deployment or project, so its name must also be different from the static files directories defined in the STATICFILES_DIRS list.
STATIC_URL = '/static/' STATICFILES_DIRS = [BASE_DIR / 'static', ] STATIC_ROOT = BASE_DIR / 'staticfiles' #new
STEP4: Check the 'django.contrib.staticfiles' in INSTALLED_APPS
Django comes with many installed apps that are listed in settings.py as
INSTALLED_APPS
. There only Django provide an installed app
'django.contrib.staticfiles'
that is responsible for handling static files in a Django project.
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
Static Directory
Now we are done with
settings.py
file for static configuration, let's create a
static
directory in the root project directory where our
manage.py
is located. To create the directory we can use the
mkdir command
mkdir static mkdir static/css mkdir static/img
The above commands will create a
static
directory in the root folder and
css
, &
img
as the static subdirectories.
static_tutorial: ? db.sqlite3 ? manage.py ? ????static ? ????css ? ????img ????static_tutorial ? asgi.py ? settings.py ? urls.py ? wsgi.py ? __init__.py
We have already configured Django which directory to look for the static files, with
STATICFILES_DIRS
identifier in
setting.py
file. Inside the
static
directory we have also created two sub directories
css
and
img
, that will contain css and images files respectively. This makes the code modular and easy to maintain. In the
css
directory let's create a style.css file that will style our web page.
/* static/css/style.css */
body { background-color: black; color: white; }
And in the
img
directory store a feature.png image.
static ? ????css ? ? style.css ? ????img ? feature.jpg
Load Static file in a Template directory
The static files are loaded in an HTML template. The web page that we see on our browser is an HTML page with loaded CSS, images and JavaScript. And Django defines a different configuration to handle template files like HTML, and XML. Similar to static file management, we need to configure the template directory in the settings.py file and create a template directory in the root folder of our project where the manage.py file is located.
#static_tutorial/setting.py
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], #new 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
In the above code, we specify the location where the Dango look for the custom templates. The
BASE_DIR / 'templates'
define the
templates
directory in the project root directory where the manage.py file is located.
Create templates directory
After specifying the templates directory location let's create the templates directory and an index.html file in it.
mkdir templates echo > templates\index.html
The above two commands will create a new directory template and the index.html file in the templates directory respectively. The above echo command will only work for windows, If you are on a mac or Linux use the touch command. Example (mac/linux)
touch templates\index.html
???templates index.html
Now let's write the index.html file and load the static files style.css and feature.png image in it using the template tags.
<!-- templates/index.html --> {% load static %} <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Tutorial</title> <!-- CSS --> <link rel="stylesheet" href="{% static 'css/style.css' %}"> </head> <body> <center> <h1>Heading</h1> <img src="{% static 'img/feature.png'%}"> </center> </body> </html>
{%load static%}
The {%load static%} is a template tag that needs to be written at the top of the HTML script, and it loads the static files in an HTML template file. If we forget to write {%load static%} in our HTML file and use the {%static%} tag we will encounter the error
Invalid block tag on line : 'static'. Did you forget to register or load this tag?
{%static%}
The {%static%} tag is defined in the under
django.contrib.staticfiles
app, this tag is used to import the specific static file in the HTML file. In the above example, we have used this tag to load the style.css and feature.png image in the index.html.
<link rel="stylesheet" href="{% static 'css/style.css' %}"> <img src="{% static 'img/feature.png'%}">
Set views.py and urls.py file
As we have not created any app in this project to render the index.html page we can create a
views.py
file in the static_tutorial directory where the settings.py file is located. for windows.
cd static_tutorial echo > views.py
views.py
from django.shortcuts import render def homepage(request): return render(request, 'index.html')
urls.py
from django.contrib import admin from django.urls import path from .views import homepage urlpatterns = [ path('admin/', admin.site.urls), path('', homepage, name='index') ]
python manage.py runserver

/static/css/
and
/static/img/
that we have defined in the
STATIC_URL
.

Serve Django Static File with Debug = False
Debug=False
.
DEBUG = False ALLOWED_HOSTS = ['*']
When we set Debug=False we also need to set the ALLOWED_HOSTS value to the server that is hosting the project. The asterisk
*
means all. In such cases when Debug mode is False and you do not want to use any other server or S3 bucket to load the static files, there you can use the
whitenoise
library that can serve the static file. Using this library is very easy all we need to do is install it for our Python environment and add it to the middleware list in the setting.py file.
Whitenoise library
With whitenoise and configuring the setting.py file, we can serve the static files in Django without relying on the server like Nginx, and Amazon S3 bucket. Many hosting providers like Heroku. OpenShift encourages the use of the whitenoise library for static files. To install whitenoise for your python environment run the following pip install command .
pip install whitenoise
After installing the whitenoise library we need to add its middleware in the settings.py file.
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', #new 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
This is not it when we set the Debug to False, this means we are using the production settings in that case Django does not use the development static file directory instead it uses the STATC_ROOT directory. In the above section, we have already defined the SATIC_ROOT to
'staticfiles'
, now the whitenoise will search for the staticfiles directory for all static files. The next command we need to run is python manage.py collectstatic, it will collect all the static files that are present in the STATICFILES_DIRS and all the other inbuilt and third-party libraries static into the directory staticfiles directory.
python manage.py collectstatic
The above command will create a directory by name staticfiles in the project root directory.
????staticfiles ? ????admin ? ? ????css ? ? ? ????vendor ? ? ? ????select2 ? ? ????fonts ? ? ????img ? ? ? ????gis ? ? ????js ? ? ????admin ? ? ????vendor ? ? ????jquery ? ? ????select2 ? ? ? ????i18n ? ? ????xregexp ? ????css ? ????img
Now if we run the server again it Django will load the CSS and image in our HTML file.
Conclusion
Django has some predefined identifiers and settings to manage static files. Some of the most important identifiers are STATIC_URL, STATICFILES_DIRS, and STATIC_ROOT, which represent the URL path, local static directories, and production static directory path. Django is not built to serve static files at the production level, it always suggests using a separate server or S3 buckets for static files. But with third-party libraries like whitenoise, we can serve static files without using any other service. People are also reading:
Leave a Comment on this Post