Версіонування статичних файлів у Django

Як змусити браузер оновлювати кешовані файли після того як вони змінились

12.09.2015

Якщо ви стикнулись з проблемою, коли ви оновили файл на вашому веб-сайті, а користувачі надалі використовують кешовану браузером версію. А там був принципово змінений функціонал у Javascript, додані нові функції чи навіть виправлені баги. Та навіть якщо змінений дизайн CSS стилів.

Перше, що приходить на думку - це перейменувати файл щоб URL змінився і браузер закешував його нову версію. Чи додати якийсь "якір"

http://example.com/static/main.js#new_file

чи як це робить Google додати версію файлу

http://example.com/static/main.js?v=2

Але якщо він використовується у багатьох файлах, і таких статичних файлів багато, то руками постійно міняти версію — не зручно.
Тому я використовую Django тег, який це робить автоматично. Він зчитує дату останньої зміни статичного файлу і додає її до URL-адреси. Якщо раптом тег не знайшов цього файлу — то нічого і не додає.

Щоб почати використовувати, додайте app_tags.py до папки з вашою аплікацією і вкажіть його в INSTALLED_APPS. Або якщо у вас вже є файл де ви зберігаєте всі фільтри і теги, то просто додайте ще один — static_version, наведений нижче.
Використовувати його дуже просто:

{% static_version 'js/main.js' %}

Готові приклади коду:

  • app_tags.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os

from django import template
from django.conf import settings

register = template.Library()

# ...
# other template tags
# ...

@register.simple_tag
def static_version(path):
    """ Returns absolute URL to static file with versioning.
    """
    full_path = os.path.join(os.path.abspath(settings.STATICFILES_DIRS[0]), os.path.normpath(path))
    try:
        # Get file modification time.
        mtime = os.path.getmtime(full_path)
        return '%s%s?%s' % (settings.STATIC_URL, path, mtime)
    except OSError:
        # Returns normal url if this file was not found in filesystem.
        return '%s%s' % (settings.STATIC_URL, path)
  • base.html
...
{% load app_tags %}
...
<link rel="icon" href="{% static_version 'img/favicon.png' %}" type="image/x-icon">
<link rel="shortcut icon" href="{% static_version 'img/favicon.png' %}" type="image/x-icon">

<link rel="stylesheet" href="{% static_version 'css/main.css' %}" type="text/css" />
<script type='text/javascript' language="javascript" src="{% static_version 'js/main.js' %}"></script>
...
  • settings.py
INSTALLED_APPS = (
  # ...
  '<app_name>.app_tags',
  # ...
)

 


Якщо вам сподобалась стаття — поділіться з друзями:  


Коментарі: