重新发明轮子并创建自己的实现有那么糟糕吗?此外,我希望低级代码(例如 nginx)在生产中而不是 python 应用程序中为我的静态文件提供服务,即使使用后端也是如此。还有一件事:我希望链接在重新计算后保持不变,所以浏览器只获取新文件。所以这是我的观点:
模板.html:
{% load md5url %}
<script src="{% md5url "example.js" %}"/>
出html:
static/example.js?v=5e52bfd3
设置.py:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
应用程序名/模板标签/md5url.py:
import hashlib
import threading
from os import path
from django import template
from django.conf import settings
register = template.Library()
class UrlCache(object):
_md5_sum = {}
_lock = threading.Lock()
@classmethod
def get_md5(cls, file):
try:
return cls._md5_sum[file]
except KeyError:
with cls._lock:
try:
md5 = cls.calc_md5(path.join(settings.STATIC_ROOT, file))[:8]
value = '%s%s?v=%s' % (settings.STATIC_URL, file, md5)
except IsADirectoryError:
value = settings.STATIC_URL + file
cls._md5_sum[file] = value
return value
@classmethod
def calc_md5(cls, file_path):
with open(file_path, 'rb') as fh:
m = hashlib.md5()
while True:
data = fh.read(8192)
if not data:
break
m.update(data)
return m.hexdigest()
@register.simple_tag
def md5url(model_object):
return UrlCache.get_md5(model_object)
注意,要应用更改,应重新启动 uwsgi 应用程序(具体来说是一个进程)。