Working with Static Files in Django
March 4, 2019, 8:55 p.m.
| Written By: Tanner S
390px-Django_logo.svg.png

One of those concepts in Django that can be tricky to truly understand is dealing with static files, such as your images, CSS stylesheets and your Javascript files. This is actually one of my pet peeves - it isn't really explained that well anywhere.

You see terms such as STATIC_URL, STATIC_ROOT and STATICFILES_DIR. What are terms and what do they mean? What do they refer to? We will try to make sense of them here.

The next few paragraphs are text heavy, so here is a picture of a puppy to break it up:

Puppy1



COLLECTSTATIC

When you run python manage.py collectstatic in your console, Django's magic starts. It will go through all of the directories (locations) defined in STATICFILES_DIRS to collect your static files. By default, it will also go through and look for subdirectories named "static" within each of your apps defined in "INSTALLED_APPS". So, let's move on to STATICFILES_DIRS.


STATICFILES_DIRS

STATICFILES_DIRS is where you tell Django where to look for your static files for the collectstatic command. It is a list of directories (locations) that you have in your project where your static files are saved.


STATIC_ROOT

Now, this is where the magic happens. We now know that when you run python manage.py collectstatic, it will loop through the directories in STATICFILES_DIRS and collect the static files, as we discussed. But, where does collectstatic put them? They will put all of the static files in to the STATIC_ROOT that you defined.


STATIC_URL

Per the Django documentation, "URL to use when referring to static files located in STATIC_ROOT". So, all of our files will be collected and saved in the STATIC_ROOT directory. However, where will we find these files when we are actually running our project? The STATIC_URL is simply the URL that is appended to our URL to find where the static files are. So, if your STATIC_URL = '/static/', then, locally, the location of your static files is localhost:8000/static. If STATIC_URL = '/motorcycle/', the location of your static files is localhost:8000/motorcycle. When you go to this URL, you will be able to access all of the file saved in STATIC_ROOT.


EXAMPLE

Let's say our settings.py contains the following:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

and

STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/staticurl/'

and you have a file structure:

myproject/
    manage.py
    myproject/
        __init__.py
        settings.py
        urls.py
        wsgi.py
    someapp/
        static/
            some-app/
                some-image.jpg
        admin.py
        apps.py
        models.py
        urls.py
        views.py
    static/
        someapp/
            some-image.jpg

When you run python manage.py collectstatic, Django will go through all of the directories in STATICFILES_DIRS as well as any subdirectories called 'static' for all apps within INSTALLED_APPS. So, it will get the files in "some-app/static/" and dump them into your defined STATIC_ROOT. STATIC_ROOT is now defined to be at myproject/static. This means that in the above folder structure, we have already executed "python manage.py collectstatic", and the files were dumped into STATIC_ROOT.

When you go to localhost:8000/staticurl/some-app/some-image.jpg, you will get the file located in your project at myproject/static/some-app/some-image.jpg. This is important when we are in our templates. Let's say we need to put some-app/some-image.jpg in one of our templates. We can use Django's template tag, {% static %}.

So, let's say we want to add the some-image.jpg in our page. We could do so by typing:

<img src = "{% static 'some-app/some-image.jpg' %}" />

This will make it so that when we run our server, the image is being displayed from the source localhost:8000/staticurl/some-app/some-image.jpg. The {% static %} syntax allows us to change our STATIC_URL to anything we want without having to go through all of our references to a static file.

CONCLUSION

I hope this helps clarify some of the terminology in Django's static files set up. If you are interested in keeping in touch with new posts, please subscribe below.