OverIQ.com

Handling Static Content in Django

Last updated on July 27, 2020


At this stage, our site looks very simple because we haven't yet added any images, CSS, and JavaScript to it. In Django, we refer to these files as Static Files as they don't change frequently. In this lesson, we will learn how to use static files in Django.

Static Files Configuration #

  1. Django provides a built-in app called staticfiles to manage static files. The first step is to make sure you have 'django.contrib.staticfiles' included in the INSTALLED_APPS list. In case 'django.contrib.staticfiles' is not listed, just add it now to the INSTALLED_APPS list. At this point, INSTALLED_APPS setting should look like this:

    djangobin/django_project/django_project/settings.py

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    #...
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'djangobin',        
    ]
    
    #...
    
  2. Just like templates, Django automatically searches for static files in the static directory of every installed app. Create a new directory named static inside the djangobin app. Inside this static directory create another directory called djangobin. Recall that to resolve the name conflicts we are following the same convention as we did while creating the templates directory.

    To manage files easily, create three new directories named css, js and images inside the static/djangobin directory. This is where we will store our static assets.

    You can also specify additional directories to search for static files using STATICFILES_DIR setting. For example:

    1
    2
    3
    4
    STATICFILES_DIR  = [
        os.path.join(BASE_DIR, 'static-dir1'),
        '/opt/dir2',
    ]
    

    However, our project is not big enough to store static files in multiple directories, so we are not going to define this setting.

  3. STATIC_URL setting defines the base URL to access static files. By default, it is set to /static/. (slashes are important). That means image file logo.png stored in djangobin/static/djangobin/images/, would be accessible at the URL http://127.0.0.1:8000/static/djangobin/images/logo.png.

    If we had instead set STATIC_URL to 'static-assets', then logo.jpg would be available at http://127.0.0.1:8000/static-assets/djangobin/images/logo.png.

Downloading Static Files #

With our directories in place, we are ready to serve static content. Download this zip file, extract it and place all css and js files in appropriate directories as indicated below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
djangobin/  <----- djangobin app directory
├── static
│   └── djangobin
│       ├── css
│       │   ├── all.css
│       │   ├── bootstrap.min.css
│       │   ├── bootstrap-select.min.css
│       │   ├── default.css
│       │   └── main.css
│       ├── images
│       └── js
│           ├── bootstrap.min.js
│           ├── bootstrap-select.min.js
│           └── jquery.js
│

Loading Static Files #

We use static tag {% static 'path/to/file' %}, to load static files, but before we use this tag, we have to load it using the following code in our template.

{% load static %}

Open base.html from sitewide templates directory (i.e. djangobin/templates/ ) and amend it as follows:

djangobin/django_project/djangobin/templates/djangobin/base.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<!DOCTYPE html>
{% load static %}
<html>
<head>
    <title>{% block title %}Default Title{% endblock %}</title>
    <link rel="stylesheet" href="{% static 'djangobin/css/bootstrap.min.css' %}">
    <script src="{% static 'djangobin/js/jquery.js' %}"></script>
</head>
<body>
{# ... #}

Save the file and visit the http://localhost:8000/add-lang/ to see the changes.

To check whether the site is loading all the files correctly or not, open Developers Tools by hitting Ctrl+Shift+J in Google Chrome. If console screen is empty, then it means all files are loading fine. On the other hand, if there is a problem then you would get 404 error in the console as follows:

If this is the case, make sure you have downloaded all the assets and placed them in the proper directory as indicated. Also, double check the path specified in the static tag in base.html file.

Setting STATIC_ROOT #

Currently, we are serving static files using Django development server. For performance and security reasons, in the production, we will be using Nginx to serve static files.

In order to achieve this, we need to set another setting called STATIC_ROOT. Open settings.py file add STATIC_ROOT setting at the end of it as follows:

djangobin/django_project/django_project/settings.py

1
2
3
4
#...
STATIC_URL = '/static/'

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

Next, create a directory named staticfiles in the project root directory.

The STATIC_ROOT specifies a location to store a copy of all the static files of the project.

To collect all the files into the STATIC_ROOT, we use ./manage.py collectstatic command. We execute this command when we are ready to deploy our app. As we are still in the development phase we will defer its execution until chapter Deployment in Django.