First time using Django! Right now, I’ve put them in a static
folder inside my main app. Is there a convention for this? Also, how to compress CSS and JS files? Is there a tool to do it? Is it possible to combine multiple CSS/JS files into one? I wanted to split my CSS file into two, is it possible to combine them? Sorry for the barrage of questions, I’ve been looking for these answers for some time!
Welcome to the world of Django!
To my knowledge at least, there isn’t a blessed One True Way to manage static files in Django, but rather lots of different ways with different advantages and drawbacks.
At my work, we use Webpack (and an assortment of plugins) to build TypeScript and Sass into JS and CSS, bundle it, minify it, and add cache-busting hashes to the file names. We then use django-webpack-loader to actually load the entry points into our templates, so that Django can find the right hashed file name.
The webpack config we use for some things at work is on GitHub here, but I don’t really get loads of time to make these sorts of things consumable by people outside the company, so I wouldn’t use it wholesale.
The Webpack approach is more or less infinitely flexible, but also rather complex (configuring Webpack is something you could write an entire book on, and it requires you to have Node.js available at build time). If you don’t need that complexity, there are other solutions that can be installed with Pip (or poetry or pipenv) and integrated directly into Django’s static asset management features.
@leigh is definitely right that there is no one blessed approach, and there is a wild variety of ways to handle static files out there. Frontend-heavy projects often use a setup as Leigh described, and I just want to add a version that I often use in smaller/less frontend-heavy projects:
Structure
Within my /static
/ directory, I’ll have subdirectories by app, if that makes sense for your projects (ie if you actually have and use mutiple apps), or just one directory with my project’s name. Additionally I’ll have a vendored
directory for all JavaScript/CSS dependencies. All of these will have subdirectories called js
, css
, and possibly assets
(for images etc).
.
└── static
├── demo
│ ├── css
│ └── js
└── vendored
├── css
└── js
I put the vendored files there by hand (most projects offer a finished bundled version for this purpose, often from a CDN for ready use). Typically I put both the minified and the non-minified file there, and decide depending on settings.DEBUG
which version to serve.You can see one example for this setup here.
This has a very noticeable number of drawbacks: I have to do updates the same way, by copying files in manually. I don’t get the luxury of automatic updates, by pinning versions etc. This is a considerable disadvantage, to my mind. On the other hand, I have no dependency on Node.js at all, which is especially nice when your project is used by many other people, and there’s no need to learn how to write Webpack configs (which can have an infinite degree of complexity).
Compression
django-compressor is pretty much what you are looking for in most cases, I think. It can combine JS and CSS files (respectively, of course, we’re not monsters!), and can also process SASS/LESS markup while it’s doing so. It provides you with the template tag compress
, which you use like this:
{% load compress %}
{% load static %}
…
{% compress js %}
<script src="{% static 'foo/bar.js' %}"></script>
<script src="{% static 'foo/baz.js' %}"></script>
{% endcompress %}
Other stuff
Deploying static files to production can be a bit of a hassle. If you run into this, whitenoise is a very nice library that will serve your static files through Django.