Make Django keep templates in memory
By default Django renders templates from disk on each request, which means if you edit a template file the changes will be reflected instantly on the site. That’s intuitive and all, but since code is kept in memory and thus code changes are not reflected until server processes are restarted, it’s easy to get yourself out of sync. I recently deployed a code/template change that depended on each other (the existing templates were incompatible with the new code) and between the time Mercurial synced files and the Apache processes were restarted I received dozens of emails about 500 errors. It was only a couple of seconds and I could not have done it any faster, but at the end of the day seeing dozens of errors is unacceptable.
Enter, django.template.loaders.cached.Loader
. It’s a template loader introduced in Django 1.2 that keeps template files in memory. I’m not sure how I missed this until now. Using the cached loader will increase your memory footprint a bit, but it will keep them in sync with the code so all your changes deploy at the same time. If you have a lot of templates the memory footprint may be more significant, but it was very minor in my case.
To use it you wrap django.template.loaders.cached.Loader
with the other template loaders you want it to cache. Since I wasn’t doing anything unusual I was able to get away with it wrapping the default loaders like so in settings.py
:
TEMPLATE_LOADERS = ( ('django.template.loaders.cached.Loader', ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', )), )
With that one change I can now deploy code and template changes and have them reflect at the same time. I am not sure why this isn’t the default, having your code update separately from your templates is illogical. Keeping it all in sync seems like common sense.
This change can be somewhat annoying while using the development web server since it automatically reloads when you change code but not when you change templates. To get around this you can either set TEMPLATE_LOADERS differently based on the value of DEBUG or override TEMPLATE_LOADERS in your local settings file(s) (assuming you have one). I’m overriding and it works fine.