为Django中的模板提供更好的静态文件服务模板标签
项目描述
它做什么
django_static是一个Django应用程序,它为您提供了各种模板标签,以更好地服务您的静态内容。它基本上重写了对静态文件的引用,并在适用的情况下对内容进行空白优化。通过使对静态内容的引用唯一(包括在名称中的时间戳),您可以非常积极地设置缓存控制设置,而无需担心升级您的代码或担心访客使用旧版本。
它启用的五个模板标签如下
staticfile获取文件的时间戳,并按您定义的方式通过符号链接创建副本。您可以使用它如下
<img src="{% staticfile "/images/foo.png" %}"/>
以下是渲染的结果
<img src="/images/foo.123456789.png"/>
…假设文件的纪元时间为123456789。
slimfile 与 staticfile 的功能相同,但不是通过创建符号链接来复制文件,而是通过 slimmer 重新编写并压缩文件。当然,这仅适用于 .js 和 .css 文件,但它运行非常快速,并且足够小心,不会破坏文件。对于 .css 文件,它会找到所有内部的相对图片并对其应用 staticfile。就像使用 staticfile 一样来使用它。
<script type="text/javascript" src="{% slimfile "/javascript/myscript.js" %}"></script>
slimcontent 用于在模板中直接压缩内容中的空白字符。它需要一个格式参数,可以是 "js"、"css" 或 "html"。例如,对于某些内联 CSS 内容,您可以这样做:
<style type="text/css"> {% slimcontent "css" %} h1, h2, h3 { font-face: 'Trebuchet MS', Verdana, Arial; } {% endslimcontent %} </style>
…并得到以下结果:
<style type="text/css"> h1,h2,h3{font-face:'Trebuchet MS',Verdana,Arial} </style>
staticall 将标签之间的所有文件合并为一个,并执行与 staticfile 相同的符号链接。写下这个:
{% staticall %} <script src="/javascript/foo.js"></script> <script src="/javascript/bar.js"></script> {% endstaticall %}
…并得到以下结果:
<script src="/javascript/foo_bar.123456789.js"></script>
slimall 执行与 slimfile 相同的压缩,但还像 staticall 一样合并文件。像 staticall 一样使用它。
{% slimall %} <script src="/javascript/foo.js"></script> <script src="/javascript/bar.js"></script> {% endslimall %}
staticall 和 slimall 完全支持 async 或 defer JavaScript 属性。这意味着:
{% slimall %} <script defer src="/javascript/foo.js"></script> <script defer src="/javascript/bar.js"></script> {% endslimall %}
…会得到以下结果:
<script defer src="/javascript/foo_bar.123456789.js"></script>
请注意,不要在同一个块中混合这两个属性,否则可能会得到意外结果。
配置
django_static 默认会被禁用。只有当你在设置模块中设置 DJANGO_STATIC = True 时,它才会真正为你工作。
默认情况下,当 django_static 对文件进行压缩或使用文件名中的时间戳创建符号链接时,它会将文件放入与原始文件相同的目录中。如果你不喜欢这样做,你可以通过设置 DJANGO_STATIC_SAVE_PREFIX = "/tmp/django-static" 来覆盖保存位置。
如果你为了设置 nginx/varnish/apache2 而想更改文件名,你可以设置 DJANGO_STATIC_NAME_PREFIX = "/cache-forever",这样将更容易编写 rewrite 规则/正则表达式,以便在 nginx/varnish/apache2 中故意设置更激进的缓存。
另一个选项是让 django_static 负责设置你的 MEDIA_URL。你可以这样做:
<img src="{{ MEDIA_URL }}{% staticfile "/foo.png" %}"/>
但是,如果你很懒,并希望 django_static 自动处理它,请设置 DJANGO_STATIC_MEDIA_URL。在 settings.py 中:
DJANGO_STATIC_MEDIA_URL = "//static.example.com"
在你的模板中:
<img src="{% staticfile "/foo.png" %}"/>
并得到以下结果:
<img src="//static.example.com/foo.1247785534.png"/>
默认情况下,如果 DJANGO_STATIC = False,DJANGO_STATIC_MEDIA_URL 将不会激活。如果你想让它激活,请设置 DJANGO_STATIC_MEDIA_URL_ALWAYS = True。
默认情况下,django_static 将在 MEDIA_ROOT 中查找源文件,但你可以告诉 django_static 在 DJANGO_STATIC_MEDIA_ROOTS 中列出的所有目录中查找。第一个匹配项将被使用。
还有一个设置 DJANGO_STATIC_USE_SYMLINK,可以设置为 False 来强制 django_static 复制文件而不是创建符号链接。
使用DJANGO_STATIC_USE_MANIFEST_FILE的高级配置
如果你在设置中启用一个名为 DJANGO_STATIC_USE_MANIFEST_FILE 的变量,你可以将文件名保存到存储在 DJANGO_STATIC_MEDIA_ROOTS 中第一个匹配目录的 manifest.json 文件中。这是在我们要手动上传 CSS 和 JavaScript 文件到 CDN 的情况下使用的。在生产环境中,当 DEBUG=False 时,django-static 将从 manifest.json 文件中获取文件名,而不是进行所有计算。
使用DJANGO_STATIC_FILE_PROXY的高级配置
如果您在设置中启用了一个名为 DJANGO_STATIC_FILE_PROXY 的变量,则可以使 django_static 生成的所有静态 URI 都通过一个函数处理。这样,例如,您可以对信息进行一些操作,如上传到 CDN。要开始,请设置配置
DJANGO_STATIC_FILE_PROXY = 'mycdn.cdn_uploader_file_proxy'
这应该与以下导入语句等价
from mycdn import cdn_uploader_file_proxy
其中 mycdn 是一个 Python 模块(例如 mycdn.py),而 cdn_uploader_file_proxy 是一个常规 Python 函数。以下是该函数的框架
def cdn_uploader_file_proxy(uri, **kwargs): return uri
现在,您可以通过这些关键字参数获取有关 django_static 对文件所做操作的详细信息。这些信息总是包含在关键字参数中
new = False checked = False changed = False notfound = False
名称应该可以自解释。它们根据 django_static 的操作结果变为 True。例如,如果您更改了 foo.js 并重新运行模板,它不是 new,但它将被 checked 和 changed。您可能得到的最重要关键字参数是 filepath。每当 django_static 真正对静态文件执行其魔法操作时,就会设置它。例如,您可能编写一个像这样的函数
on_my_cdn = {} def cdn_uploader_file_proxy(uri, filepath=None, new=False, changed=False, **kwargs): if filepath and (new or changed): on_my_cdn[uri] = upload_to_my_cdn(filepath) return on_my_cdn.get(uri, uri)
使用DJANGO_STATIC_FILENAME_GENERATOR的高级配置
默认情况下,django-static 使用时间戳为您的组合文件生成文件名。您可以通过在设置中设置它来使用自己的文件名生成函数,如下所示
DJANGO_STATIC_FILENAME_GENERATOR = 'myapp.filename_generator'
这应该与以下导入语句等价
from myapp import filename_generator
其中 myapp 是一个 Python 模块,而 filename_generator 是一个常规 Python 函数。以下是该函数的框架
def filename_generator(file_parts, new_m_time): return ''.join([file_parts[0], '.%s' % new_m_time, file_parts[1]])
使用DJANGO_STATIC_COMBINE_FILENAMES_GENERATOR的高级配置
默认情况下,django-static 通过连接文件名来为您的组合文件生成文件名。您也可以通过在设置中设置它来使用自己的文件名生成函数,如下所示
DJANGO_STATIC_COMBINE_FILENAMES_GENERATOR = 'myapp.combine_filenames'
这应该与以下导入语句等价
from myapp import combine_filenames
其中 myapp 是一个 Python 模块,而 combine_filenames 是一个常规 Python 函数。以下是该函数的框架
path = None names = [] extension = None timestamps = [] for filename in filenames: name = os.path.basename(filename) if not extension: extension = os.path.splitext(name)[1] elif os.path.splitext(name)[1] != extension: raise ValueError("Can't combine multiple file extensions") for each in re.finditer('\.\d{10}\.', name): timestamps.append(int(each.group().replace('.',''))) name = name.replace(each.group(), '.') name = os.path.splitext(name)[0] names.append(name) if path is None: path = os.path.dirname(filename) else: if len(os.path.dirname(filename)) < len(path): path = os.path.dirname(filename) new_filename = '_'.join(names) if timestamps: new_filename += ".%s" % max(timestamps) new_filename = new_filename[:max_length] new_filename += extension return os.path.join(path, new_filename)
压缩过滤器
默认(cssmin)
如果已安装,django-static 默认使用 cssmin。在此获取源代码:https://github.com/zacharyvoase/cssmin
使用jsmin
如果您想使用 jsmin 而不是默认的 js_slimmer,只需在 settings.py 文件中设置该变量即可
DJANGO_STATIC_JSMIN = True
使用Google Closure Compiler
如果您想使用 Google Closure Compiler 来优化您的 JavaScript 文件,首先必须下载 compiler.jar 文件并确保您的系统可以运行 Java。假设您将其下载到 /usr/local/bin,然后在 settings.py 文件中设置此变量
DJANGO_STATIC_CLOSURE_COMPILER = '/usr/local/bin/compiler.jar'
如果由于某些原因编译器在您的 JavaScript 上失败,它不会停止文件的提供,但文件将不会进行空格优化,错误将以大注释块的形式插入到生成的 JavaScript 文件中。
使用YUI Compressor
YUI Compressor 是一个 JavaScript 和 CSS 压缩器,它需要一个 Java 运行时。就像 Google Closure Compiler 一样,您需要下载 jar 文件,然后在 settings.py 中设置类似以下内容
DJANGO_STATIC_YUI_COMPRESSOR = '/path/to/yuicompressor-2.4.2.jar'
如果您配置了 Google Closure Compiler 和 YUI Compressor,则 Google Closure Compiler 将是 JavaScript 压缩的首选。
使用slimmer
slimmer 是一个全 Python 包,能够优化 CSS、HTML、XHTML 和 JavaScript 的空白。它比 YUI Compressor 和 Google Closure 快,但这种速度差异是由于在 Java 文件之间桥接的启动和停止时间。
如何与nginx集成
项目详情
下载文件
下载适用于您的平台的文件。如果您不确定选择哪一个,请了解更多关于安装包的信息。