跳转到主要内容

为Django中的模板提供更好的静态文件服务模板标签

项目描述

它做什么

django_static是一个Django应用程序,它为您提供了各种模板标签,以更好地服务您的静态内容。它基本上重写了对静态文件的引用,并在适用的情况下对内容进行空白优化。通过使对静态内容的引用唯一(包括在名称中的时间戳),您可以非常积极地设置缓存控制设置,而无需担心升级您的代码或担心访客使用旧版本。

它启用的五个模板标签如下

  1. staticfile获取文件的时间戳,并按您定义的方式通过符号链接创建副本。您可以使用它如下

    <img src="{% staticfile "/images/foo.png" %}"/>

    以下是渲染的结果

    <img src="/images/foo.123456789.png"/>

    …假设文件的纪元时间为123456789。

  2. slimfilestaticfile 的功能相同,但不是通过创建符号链接来复制文件,而是通过 slimmer 重新编写并压缩文件。当然,这仅适用于 .js.css 文件,但它运行非常快速,并且足够小心,不会破坏文件。对于 .css 文件,它会找到所有内部的相对图片并对其应用 staticfile。就像使用 staticfile 一样来使用它。

    <script type="text/javascript"
      src="{% slimfile "/javascript/myscript.js" %}"></script>
  3. 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>
  4. staticall 将标签之间的所有文件合并为一个,并执行与 staticfile 相同的符号链接。写下这个:

    {% staticall %}
    <script src="/javascript/foo.js"></script>
    <script src="/javascript/bar.js"></script>
    {% endstaticall %}

    …并得到以下结果:

    <script src="/javascript/foo_bar.123456789.js"></script>
  5. slimall 执行与 slimfile 相同的压缩,但还像 staticall 一样合并文件。像 staticall 一样使用它。

    {% slimall %}
    <script src="/javascript/foo.js"></script>
    <script src="/javascript/bar.js"></script>
    {% endslimall %}

staticallslimall 完全支持 asyncdefer 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 = FalseDJANGO_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,但它将被 checkedchanged。您可能得到的最重要关键字参数是 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集成

阅读 peterbe.com 上的此博客条目

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪一个,请了解更多关于安装包的信息。

源分发

django-static-1.5.6.tar.gz (26.8 kB 查看哈希值)

上传时间

构建分发

django_static-1.5.6-py2-none-any.whl (32.7 kB 查看哈希值)

上传时间 Python 2

支持