Handling Static Content in Django

At this stage our website 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 an in-built app called staticfiles to manange 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 looks like this:

    TGDB/django_project/django_project/settings.py

     ...
     INSTALLED_APPS = [
         'django.contrib.admin',
         'django.contrib.auth',
         'django.contrib.contenttypes',
         'django.contrib.sessions',
         'django.contrib.messages',
         'django.contrib.staticfiles',
         'blog',
         'cadmin'
     ]
     ...
    
  2. Just like the templates, Django automatically searches for static files in the static directory of every installed app. Create a new directory named static inside the blog app. Inside this static directory create another directory called blog. Recall that here we are following the same convention we did while creating the templates directory.

    To manage CSS, JS and images files easily, create three new directories named css, js and images inside the blog directory (inside the static directory) we created above.

    What about sitewide static files i.e files which is used by multiple apps ?

  3. Create a new directory called static in the Django project root directory (TGDB/django_project), the same place where manange.py is located.

    sitewide-static-directory-location-VPDFNC.png

    In Django, STATICFILES_DIRS setting is used to list additional directories where Django will search for static files, in addition to static directory of every installed app. This setting is not set by default. To make Django search for static files in the sitewide static directory we created above, add the following code at the end of the settings.py, just below the email setting.

    TGDB/django_project/django_project/settings.py

     ...
     ## STATIC FILES ##
    
     STATICFILES_DIRS = [
         os.path.join(BASE_DIR, 'static'),    
     ]
     ...
    

    Although, we don't need this directory in our project, just let it be here, it will remind you where to keep your sitewide static files, in case you need them at a later date.

  4. STATIC_URL is another common setting which comes into play when we use static files. What does it do ? It defines a string which is used to access static files. By default it contains '/static/' (slashes are important). Here is how it works - Let's say there is a image called logo.jpg in the sitewide static directory. To access this file point your browser to http://127.0.0.1:8001/static/logo.jpg. Notice the string "/static/" in the URL http://127.0.0.1:8001/static/logo.jpg is coming from STATIC_URL setting.

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

    Similarly, to access blog app's reset.css which is stored in blog/static/blog/css/style.css visit http://127.0.0.1:8000/static/blog/css/reset.css.

Downloading Static Files #

With our directories in place, we are ready to serve static content. Download the following static files and store them in the directory as indicated.

reset.css and style.css - store CSS files in the directory blog/static/blog/css.
jquery.js - store it in the directory blog/static/blog/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 %}

Let's now load our static files. Open blog app's base.html from the directory blog/templates/blog/ and amend the file as follows:

TGDB/django_project/blog/templates/blog/base.html

...
</head>
    <title>{% block title %}The Great Django Blog{% endblock %}</title>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans">
    {% load static %}
    <link rel="stylesheet" href="{% static 'blog/css/reset.css' %}">
    <link rel="stylesheet" href="{% static 'blog/css/style.css' %}">
    <script src="{% static 'blog/js/jquery.js' %}"></script>
    </head>
<body>

    <div class="navbar">
...

Note that in addition to loading static files we are also loading an external CSS file for the fonts from Google Fonts, just below the title tag. Save the file and visit the http://127.0.0.1:8000/ to see the changes.

home-page-with-css-and-js.png

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 file are loading correctly. On the other hand, if there is a problem in loading files you would get 404 error in console as follows:

404-errors-in-js-console.png

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

Currently, we are serving static files using Django development server. Although, it's working but it is not the recommended way to serve static files in production. We will learn how to deploy static files in using Nginx server in Django Deployment lesson.