python - 使Django中静态文件的浏览器缓存无效

标签 python django caching static

在 Django 中我们有 ManifestStaticFilesStorage 用于缓存静态文件,但它在 Django 和浏览器之间工作,但我想要在用户和浏览器之间正确缓存。

想要:每次更改静态文件时,都会重新计算文件的哈希值,并且浏览器缓存会失效,用户无需运行 --collectstatic --no 就可以看到新的静态文件,无需 F5 adn -输入

我的代码现在不工作了: settings.py

STATICFILES_STORAGE = 'auth.utils.HashPathStaticFilesStorage'

CACHES = {
    'staticfiles': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'staticfiles',
        'TIMEOUT': 3600 * 24 * 7,
        'MAX_ENTRIES': 100,
    }
}

auth.utils.py:

# -*- coding: utf-8 -*-

import time

from hashlib import sha384

from django.conf import settings
from django.core.cache import cache
from django.contrib.staticfiles.storage import ManifestStaticFilesStorage


try:
    ACCURACY = settings.STATICFILES_HASH_ACCURACY
except AttributeError:
    ACCURACY = 12

try:
    KEY_PREFIX = settings.STATICFILES_HASH_KEY_PREFIX
except AttributeError:
    KEY_PREFIX = 'staticfiles_hash'

class HashPathStaticFilesStorage(ManifestStaticFilesStorage):
    """A static file storage that returns a unique url based on the contents
    of the file. When a static file is changed the url will also change,
    forcing all browsers to download the new version of the file.

    The uniqueness of the url is a GET parameter added to the end of it. It
    contains the first 12 characters of the SHA3 sum of the contents of the
    file.

    Example: {% static "image.jpg" %} -> /static/image.jpg?4e1243

    The accuracy of the hash (number of characters used) can be set in
    settings.py with STATICFILES_HASH_ACCURACY. Setting this value too low
    (1 or 2) can cause different files to get the same hash and is not
    recommended. SHA3 hashes are 40 characters long so all accuracy values
    above 40 have the same effect as 40.

    The values can be cached for faster performance. All keys in the cache have
    the prefix specified in STATICFILES_HASH_KEY_PREFIX in setings.py. This
    value defaults to 'staticfiles_hash'
    """

    @property
    def prefix_key(self):
        return "%s:%s" % (KEY_PREFIX, 'prefix')

    def invalidate_cache(self, nocache=False):
        """Invalidates the cache. Run this when one or more static files change.
        If called with nocache=True the cache will not be used.
        """
        value = int(time.time())
        if nocache:
            value = None
        cache.set(self.prefix_key, value)

    def get_cache_key(self, name):
        hash_prefix = cache.get(self.prefix_key)
        if not hash_prefix:
            return None
        key = "%s:%s:%s" % (KEY_PREFIX, hash_prefix, name)
        return key

    def set_cached_hash(self, name, the_hash):
        key = self.get_cache_key(name)
        if key:
            cache.set(key, the_hash)

    def get_cached_hash(self, name):
        key = self.get_cache_key(name)
        if not key:
            return None
        the_hash = cache.get(key)
        return the_hash

    def calculate_hash(self, name):
        path = self.path(name)
        try:
            the_file = open(path, 'rb')
            the_hash = sha384(the_file.read()).hexdigest()[:ACCURACY]
            the_file.close()
        except IOError:
            return ""
        return the_hash

    def get_hash(self, name):
        the_hash = self.get_cached_hash(name)
        if the_hash:
            return the_hash
        the_hash = self.calculate_hash(name)
        self.set_cached_hash(name, the_hash)
        return the_hash

    def url(self, name):
        base_url = super(HashPathStaticFilesStorage, self).url(name)
        the_hash = self.get_hash(name)
        if "?" in base_url:
            return "%s&%s" % (base_url, the_hash)
        return "%s?%s" % (base_url, the_hash)

最佳答案

我只是用这个很简单的想法

<img src="{{ company.logo.url }}?v={% now 'U' %}" />

使用 ?v= 强制版本并将版本设置为当前时间戳 {% now 'U' %} 这样它会随着每个请求而改变

关于python - 使Django中静态文件的浏览器缓存无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46576891/

相关文章:

python - 如何使用非标准分隔符从词汇创建 DF?

python - Python 中输入的新行

python - 如何使用 PyDev 调试 Django 单元测试?

python - Celery 的 "autodiscover_tasks"函数的作用是什么?

缓存与 Tempview

jquery - 在 jQuery 中缓存 $(this) 是最佳实践吗?

java - 防止 Spring 尝试读取旧的资源流

class - 如何使用额外的方法在 Sage 中创建新的 Graph 类?

python - 将 pytest 工作目录更改为测试用例目录

python - Django 文件位置