CSS, JavaScript, and typefaces are all essential components of any modern online application. Django offers a lot of flexibility in terms of how these files are used, but this might be confusing for newbies. The Django web server will provide static files for local development, and only little configuration is necessary. The external package WhiteNoise, as well as various additional processes, are necessary for production.
We’ll look at how to set up static files for local development and later production in this lesson.
Django Serve Static Files In Local Development
Multiple apps are frequently found in a single Django project. Django looks for a static directory containing static files within each app by default. So, if one of your apps is called blog, and you want to add a CSS file called base.css to it, you’ll need to create a new directory called blog/static, then add the file to it, making the address blog/static/style.css.
Because most Django projects have many apps and shared static files, it’s normal to create a top-level folder called static instead. The mkdir command can be used to add this from the command line:
Copied!$ mkdir static
There is a single line of setup for static files named STATIC URL near the bottom of the settings.py file, which is the location of static files in our project.
Copied!# settings.py STATIC_URL = '/static/'
Static files will be kept at http://127.0.0.1:8000/static/ or http://localhost:8000/static/, respectively. We must add a configuration for STATICFILES DIRS telling Django to also look within a static folder in order to notify Django of our new top-level static folder.
Copied!# settings.py STATIC_URL = '/static/' STATICFILES_DIRS = (str(BASE_DIR.joinpath('static')),) # new
This example makes use of pathlib, which is loaded by default in Django 3.1+. You’d use STATICFILES DIRS = [os.path.join(BASE DIR,’static’)] if you’re using a settings.py file from 3.0 or earlier.
Create subfolders for each sort of static file, such as css, js, and image, within the new static folder. These can be added using the mkdir command on the command line:
Copied!$ mkdir static/css $ mkdir static/js $ mkdir static/img
All of your static assets can now be added. As a result, the base.css file would be at static/css/base.css. The styling will not be available if you run the local webserver now (python manage.py runserver). This is due to the fact that static assets must be loaded into the templates directly.
Loading Static Files Into Templates
In a template, loading static files is a two-step process:
- add
{% load static %}
at the top of the template - add the {% static %} template tag with the proper link
Let’s pretend your Blog project has a base.html file. The procedure for performing both updates would be as follows:
Copied!<!-- templates/base.html --> {% load static %} <!DOCTYPE html> <html> <head> <title>Learn Django</title> <link rel="stylesheet" href="{% static 'css/base.css' %}"> </head> ... </html>
The changes will be visible if you save and reload the web page. The following is how to add links to images in an img folder or JavaScript in a js folder:
Copied!<img src="{% static 'img/path_to_img' %}"> <script src="{% static 'js/base.js' %}"></script>
Collect Static Files Using collectstatic
Static files will be served by the local Django server, but not by a production server like Gunicorn or uWSGI. As a result, Django includes the collectstatic command, which compiles all static files into a single directory appropriate for production deployment. The STATIC ROOT
option specifies the absolute path to these gathered files, which are commonly referred to as staticfiles. The last component is STATICFILES STORAGE
, which is the file storage engine utilized when using the collectstatic command to collect static files. It is set to django.contrib.staticfiles.storage.StaticFilesStorage by default.
As a result, four static file configurations are necessary, and the python manage.py collectstatic command must be executed each time there is a change to recompile all static components into a single directory.
Copied!# settings.py STATIC_URL = '/static/' STATICFILES_DIRS = (str(BASE_DIR.joinpath('static')),) # new STATIC_ROOT = str(BASE_DIR.joinpath('staticfiles')) # new STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage' # new
Then run the command python manage.py collectstatic
Copied!(env) $ python manage.py collectstatic
A new staticfiles directory with folders for admin (the built-in admin has its own static files), staticfiles.json, and whatever directories are in your static folder will be created.
If you add a new static file to static, it will be accessible locally. Unless you execute python manage.py collectstatic every time, it’s only for production where the file won’t be present. As a result, collecting static data is commonly included in deployment processes and is done by default on Heroku.
Overview
-
STATIC_URL
is the URL location of static files located inSTATIC_ROOT
-
STATICFILES_DIRS
tells Django where to look for static files in a Django project, such as a top-levelstatic
folder -
STATIC_ROOT
is the folder location of static files whencollectstatic
is run -
STATICFILES_STORAGE
is the file storage engine used when collecting static files with thecollectstatic
command.
Django Serve Static Files In Production
Even though we’ve properly configured our Django project to gather static files, there’s one more step that isn’t covered in the official Django documentation. This is the WhiteNoise setup for serving static files in production. The first step is to install the most recent package version:
Copied!(env) $ pipenv install whitenoise==5.1.0
Then make three changes to the settings.py file:
- add
whitenoise
to theINSTALLED_APPS
above the built-instaticfiles
app - under
MIDDLEWARE
, add a newWhiteNoiseMiddleware
on the third line - change
STATICFILES_STORAGE
to useWhiteNoise
.
Copied!# settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'whitenoise.runserver_nostatic', # new 'django.contrib.staticfiles', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', # new 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ... STATIC_URL = '/static/' STATICFILES_DIRS = (str(BASE_DIR.joinpath('static')),) STATIC_ROOT = str(BASE_DIR.joinpath('staticfiles')) STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' # new
That concludes the tutorial. So that the files are stored using WhiteNoise, run python manage.py collectstatic
once again. Then, with confidence, deploy to your preferred hosting platform.
Conclusion
In this article, you’ve learnt how to work with and serve static files in Django Web Development framework for both local development and production. As always, If you have found this article useful do not forget to share it and leave a comment if you have any questions. Happy Coding
Leave a Reply