yaobin.wen

Yaobin's Blog

View on GitHub
7 February 2017

How to Share Static Files in Django

by yaobin.wen

When I was working on my Django project I came across the situation that multiple apps were actually using the same static files. Being a software engineer who has been taught about the DRY(Don’t Repeat Yourself) principle through the entire career, I figured out the solution to share these files by reading someone else’s blog as well as skimming through the Django documents.

The solution consists of the following steps:

Here are more details about each step. Please note that this article is written on the basis of the Django’s official tutorials so it should work for you if you also base your work on the same tutorial.

Step 1: Add the STATICFILES_DIRS Variable

In the project’s settings.py file, you should be able to find a variable at the end of it:

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/

STATIC_URL = '/static/'

Add another Python list after it:

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "__shared__"),
]

This tells Django to search for static files in addition to the path specified in STATIC_URL. The relevant document is here: STATICFILES_DIRS.

Step 2: Put the Static Files to the Shared Location

In Step 1, the BASE_DIR is defined in the settings.py as well:

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

If you are following Django’s tutorial, in which the sample project has the following structure:

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py

The BASE_DIR points to the mysite inside the outer mysite. Therefore, the additional static file location we added in Step 1 should be:

mysite/mysite/__shared__

So let’s create this directory and make the directory structure look like below:

mysite/
    __shared__/
        images/
            background.png
        style.css
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py

Step 3: Modify the HTML Templates

The HTML templates in Django’s official tutorials refer to the static files as follows:

HTML pages:

<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />

style.css:

body {
    background: white url("images/background.png") no-repeat right bottom;
}

You need to adjust the relative paths accordingly. For example, because now we’ve put the style.css immediately under the shared_ directory without any intermediate sub-directories, we should no longer use the polls directory, so we should modify the HTML template as:

<link rel="stylesheet" type="text/css" href="{% static 'style.css' %}" />

When Django’s static file finder looks for the style.css as specified in the code {% static "style.css" %} , it first searches in the static directory of that app. Because this directory doesn’t exist after we move the static files to the shared location, the finder then searches the additional static file folders which contains shared, and is able to find and use it. If we don’t remove the intermediate _polls, the finder cannot find the file shared/polls/style.css.

More Notes

I also read the blog Share static files between apps in Django. However, this article doesn’t discuss how to modify the HTML template accordingly. The template refers to the style.css with {{STATIC_URL}}/style.css which doesn’t work because STATIC_URL is always static and doesn’t include the newly added common-static in.

Tags: Tech