静态资产

asset python中是否包含任何文件 package 哪个是 not 一个python源代码文件。例如,以下每项都是一项资产:

  • 包含在python包中或包含在python包的任何子目录中的gif图像文件。

  • 包含在python包中或包含在python包的任何子目录中的css文件。

  • 包含在python包中或包含在python包的任何子目录中的javascript源文件。

  • 包中没有 __init__.py 在它里面(如果它拥有 __init__.py 它会 be 一个包裹)

  • ChameleonMako 包含在python包中的模板文件。

资产的使用在大多数Web开发项目中都很常见。例如,当您创建 Pyramid 应用程序使用 cookiecutter ,如中所述 创建项目 ,表示应用程序的目录包含一个python package . 在这个python包中,有许多文件目录,这些文件是静态资产。例如,有一个 static 目录,其中包含 .css.js.gif 文件夹。当用户访问应用程序URL时,将传递这些资产文件。

了解资产规格

假设你创造了一个 Pyramid 使用 Chameleon ZPT模板通过 pyramid.renderers.render_to_response() 应用程序编程接口。例如,应用程序可以使用 asset specification myapp:templates/some_template.ptviews.py 文件内 myapp 包裹:

1from pyramid.renderers import render_to_response
2render_to_response('myapp:templates/some_template.pt', {}, request)

“在引擎盖下”,当这个API被调用时, Pyramid 试图从字符串中找出意义 myapp:templates/some_template.pt 由开发商提供。此字符串是 asset specification . 它由两部分组成:

  • 这个 包名 (myapp

  • 这个 资产名称 (templates/some_template.pt ,相对于包目录。

这两部分由一个冒号隔开。 : 性格。

Pyramid 使用Python pkg_resources 将包名称和资产名称解析为绝对(操作系统特定)文件名的API。它最终将这个解析的绝对文件系统路径传递给变色龙模板引擎,然后使用它来加载、解析和执行模板文件。

资产规格有第二种形式:A 相对的 资产规格。在某些情况下,您可以从规范中省略包名称,而不是使用包含包名称的“绝对”资产规范。例如,您可以使用 templates/mytemplate.pt 而不是 myapp:templates/some_template.pt . 此类资产规格通常与“当前套餐”相关。“当前包”通常是包含 uses 资产规格。 Pyramid 接受相关资产规范的API通常在各自的文档中描述资产的相对性。

服务静态资产

Pyramid 可以将静态资产文件从文件系统上的目录提供给应用程序用户的浏览器。使用 pyramid.config.Configurator.add_static_view() 教导 Pyramid 服务静态资产,如javascript和css文件。此机制使静态文件目录以相对于应用程序根URL的名称可用,例如, /static 或作为外部URL。

备注

add_static_view() 不能为单个文件提供服务,也不能为静态文件目录提供直接相对于 Pyramid 应用。有关这些功能,请参见 高级:使用可调用视图服务静态资产 .

下面是一个使用 add_static_view() 它将提供来自 /var/www/static 运行的计算机的目录 Pyramid 应用程序作为URL位于 /static URL前缀。

1# config is an instance of pyramid.config.Configurator
2config.add_static_view(name='static', path='/var/www/static')

这个 name 表示URL 前缀 . 以便保存在 path 要提供的目录,请求其中一个目录的URL必须以该前缀开头。在上面的例子中, namestaticpath/var/www/static . 在英语中,这意味着您希望为居住在 /var/www/static 作为 /static URL前缀。因此,文件 /var/www/static/foo.css 当用户访问应用程序的URL时将返回 /static/foo.css .

名为的静态目录 path 可以递归地包含子目录,并且任何子目录都可以保存文件;这些子目录将按预期由静态视图解析。这个 Content-Type 静态视图为每个特定类型的文件返回的头取决于其文件扩展名。

默认情况下,所有文件通过 add_static_view() 完全匿名的用户可以访问。但是,可能需要简单的授权。除了传递所需的 namepath 参数,也传递 permission 关键字参数 add_static_view() . 的值 permission 参数表示 permission 用户必须具有与当前 context 当调用静态视图时。用户需要拥有此权限才能查看由 path 静态视图的。如果静态资产必须由更复杂的授权方案保护,请参见 高级:使用可调用视图服务静态资产 .

下面是另一个使用 asset specification 而不是绝对路径 path 参数。说服 add_static_view() 把文件放在 /static 来自URL的URL a/b/c/static 名为的python包的目录 some_package ,我们可以使用完全合格的 asset specification 作为 path

1# config is an instance of pyramid.config.Configurator
2config.add_static_view(name='static', path='some_package:a/b/c/static')

这个 path 提供给 add_static_view() 可能是完全合格的 asset specification绝对路径 .

而不是表示URL前缀, name 调用的参数 add_static_view() 可交替为 URL . 到目前为止,我们看到的每个示例都显示了 name 作为URL前缀的参数。然而,何时 name 是一个 URL ,可以从外部Web服务器提供静态资产。在这种模式下, name 在使用生成URL时用作URL前缀 pyramid.request.Request.static_url() .

例如, add_static_view() 可以喂 name 论点是 http://example.com/images

1# config is an instance of pyramid.config.Configurator
2config.add_static_view(name='http://example.com/images',
3                       path='mypackage:images')

因为 add_static_view() 提供了一个 name URL的参数 http://example.com/images ,后续呼叫 static_url() 以开头的路径 path 参数传递给 add_static_view() 将生成类似于 http://example.com/images/logo.png . 正在侦听的外部Web服务器 example.com 必须将其自身配置为正确响应此类请求。这个 static_url() 本章后面将更详细地讨论API。

为预压缩资产服务

在 2.0 版本加入.

可以配置 Pyramid 为预压缩的静态资产提供服务。这可以大大减少为资产提供服务所需的带宽—大多数现代浏览器都支持 gzipdeflatebr (brotli)编码响应。客户端使用 Accept-Encoding HTTP标头。例如, Accept-Encoding: gzip, default, br . 然后,响应将包含带有 Content-Encoding 标头设置为匹配的编码。此功能假定静态资产存在未编码的 (identity 编码)以及零或更多编码格式。如果文件的编码版本丢失,或者客户机没有声明对编码版本的支持,则返回未编码版本。

为了在应用程序中配置此功能,第一步是压缩资产。例如,更新静态资源管道以导出 .gz 每个文件的版本。第二,增加 content_encodings=['gzip'] 调用时 pyramid.config.Configurator.add_static_view() .

编码的文件扩展名由 mimetypes.encodings_map . 因此,如果缺少所需的编码,则需要在此处添加:

import mimetypes
mimetypes.encodings_map['.br'] = 'br'  # add brotli

不是每个文件都支持每种编码,但是 Pyramid 不会为未声明的编码提供服务。

生成静态资源URL

当一个 add_static_view() 方法用于注册静态资产目录,这是一个名为 pyramid.request.Request.static_url() 可用于为位于静态注册所命名目录之一的资产生成适当的URL path 属性。

例如,假设您创建了一组静态声明,如下所示:

1config.add_static_view(name='static1', path='mypackage:assets/1')
2config.add_static_view(name='static2', path='mypackage:assets/2')

这些声明创建URL可访问的目录,这些目录的URL以 /static1/static2 ,分别。中的资产 assets/1 目录 mypackage 当用户访问以 /static1 以及 assets/2 目录 mypackage 当用户访问以 /static2 .

在这种配置中,不需要“手工”生成指向静态资产的URL。相反,使用 static_url() API为您生成它们。例如:

1from pyramid.renderers import render_to_response
2
3def my_view(request):
4    css_url = request.static_url('mypackage:assets/1/foo.css')
5    js_url = request.static_url('mypackage:assets/2/foo.js')
6    return render_to_response('templates/my_template.pt',
7                              dict(css_url=css_url, js_url=js_url),
8                              request=request)

如果运行系统的请求“应用程序URL”是 http://example.com , the css_url 上面生成的是: http://example.com/static1/foo.css . 这个 js_url 上面生成的 http://example.com/static2/foo.js .

使用 static_url() 如果需要更改 name 对于静态URL声明,生成的URL将在重命名后继续正确解析。

URL也可以由 static_url() 到活动的静态资产 外部 这个 Pyramid 应用。当 add_static_view() 与输入到的路径关联的API static_url() 是一个 URL 而不是视图名称。例如, name 论点可能是 http://example.compath 可能给出 mypackage:images

1config.add_static_view(name='http://example.com/images',
2                      path='mypackage:images')

在这种配置下,由 static_url 对于以 mypackage:images 将以前缀 http://example.com/images

1request.static_url('mypackage:images/logo.png')
2# -> http://example.com/images/logo.png

使用 static_url()add_static_view() 使在生产过程中可以在单独的Web服务器上放置静态媒体(如果 name 参数 add_static_view() 是一个URL),同时将静态媒体包保持在内部,并在开发期间由开发Web服务器提供服务(如果 name 参数 add_static_view() 是URL前缀)。

例如,我们可以定义 custom setting 已命名 media_location 当我们的资产托管在cdn上时,我们可以将其设置为生产中的外部URL。

1media_location = settings.get('media_location', 'static')
2
3config = Configurator(settings=settings)
4config.add_static_view(path='myapp:static', name=media_location)

现在,我们可以选择在ini文件中定义设置:

1# production.ini
2[app:main]
3use = egg:myapp#main
4
5media_location = http://static.example.com/

通过引用文件系统上的绝对路径,还可以为位于源代码之外的资产提供服务。实现这一点有两种方法。

第一, add_static_view() 支持直接使用绝对路径而不是资产规格。这可以按预期工作,在文件或文件夹中查找文件,并在应用程序内或外部的某个URL上为其提供服务。不幸的是,这种技术有一个缺点,即不可能使用 static_url() 方法生成URL,因为它基于资产规范工作。

在 1.6 版本加入.

第二种方法(在金字塔1.6+中可用)使用资产覆盖API,如 压倒一切的资产 部分。然后可以配置一个“虚拟”包,该包将从绝对路径为其文件或文件夹提供服务。

config.add_static_view(path='myapp:static_images', name='static')
config.override_asset(to_override='myapp:static_images/',
                      override_with='/abs/path/to/images/')

从这个配置中,现在可以使用 static_url() 通过执行以下操作生成文件夹中数据的URL request.static_url('myapp:static_images/foo.png') . 虽然没有必要 static_images 文件或文件夹实际存在于 myapp 包装,重要的是 myapp 部分指向有效的包。如果文件夹确实存在,那么如果两个位置都存在文件名,则优先使用覆盖文件夹。

缓存中断

在 1.6 版本加入.

为了最大限度地提高Web应用程序的性能,通常需要限制特定客户机请求相同静态资产的次数。理想情况下,客户机将“永远”缓存一个特定的静态资产,要求将其一次性发送给客户机。HTTP协议允许您发送带有HTTP响应的头,该响应可以指示客户机缓存特定资产一段时间。只要客户机在其缓存中有资产的副本,并且该缓存未过期,客户机将使用缓存的副本,而不是从服务器请求新副本。向客户机发送静态资产的缓存头的缺点是,在某个时刻静态资产可能会发生变化,然后您将希望客户机加载该资产的新副本。在正常情况下,您只需要等待客户机的缓存副本过期,然后他们才能获得静态资源的新版本。

解决这个问题的常用方法是 cache busting . 缓存总线方案通常涉及为静态资产生成一个URL,当静态资产更改时,该URL会发生更改。通过这种方式,头可以与静态资产一起发送,指示客户机将资产缓存很长时间。当静态资源更改时,用于在网页中引用该资源的URL也会更改,因此客户端将其视为新资源并请求该资源,而不考虑为该资源的旧URL设置的任何缓存策略。

Pyramid 可以配置为使用 add_cache_buster()

1import time
2from pyramid.static import QueryStringConstantCacheBuster
3
4# config is an instance of pyramid.config.Configurator
5config.add_static_view(name='static', path='mypackage:folder/static/')
6config.add_cache_buster(
7    'mypackage:folder/static/',
8    QueryStringConstantCacheBuster(str(int(time.time()))))

添加cachebuster指示 Pyramid 要将静态资产的当前时间添加到资产URL中的查询字符串中,请执行以下操作:

1js_url = request.static_url('mypackage:folder/static/js/myapp.js')
2# Returns: 'http://www.example.com/static/js/myapp.js?x=1445318121'

当Web服务器重新启动时,时间常数将更改,因此其URL也将更改。

备注

缓存总线是一个固有的复杂主题,因为它集成了资产管道和Web应用程序。预期并期望应用程序作者根据自己资产管道的属性编写自己的缓存buster实现。见 自定义缓存管理器 关于自己写作的信息。

禁用高速缓存buster

在某些情况下(例如,开发),在不更改对 add_cache_buster() . 要执行此操作,请设置 PYRAMID_PREVENT_CACHEBUST 环境变量或 pyramid.prevent_cachebust 配置值为真值。

自定义缓存管理器

呼叫 add_cache_buster() 可以使用实现接口的任何对象 ICacheBuster .

Pyramid 带有非常简单的 QueryStringConstantCacheBuster ,这会将您提供的任意标记添加到资产URL的查询字符串中。这几乎不是您在生产中想要的,因为它不允许对单个资产进行细粒度的分解。

为了实现自己的缓存buster,可以从头开始编写自己的类,该类实现 ICacheBuster 接口。或者,您可以选择子类化一个现有的实现。最有可能的情况之一是,您希望更改生成资产令牌的方式。这样做只是子类 QueryStringCacheBuster 定义一个 tokenize(pathspec) 方法。下面是一个使用git获取当前提交哈希的示例:

 1import os
 2import subprocess
 3from pyramid.static import QueryStringCacheBuster
 4
 5class GitCacheBuster(QueryStringCacheBuster):
 6    """
 7    Assuming your code is installed as a Git checkout, as opposed to an egg
 8    from an egg repository like PYPI, you can use this cachebuster to get
 9    the current commit's SHA1 to use as the cache bust token.
10    """
11    def __init__(self, param='x', repo_path=None):
12        super(GitCacheBuster, self).__init__(param=param)
13        if repo_path is None:
14            repo_path = os.path.dirname(os.path.abspath(__file__))
15        self.sha1 = subprocess.check_output(
16            ['git', 'rev-parse', 'HEAD'],
17            cwd=repo_path).strip()
18
19    def tokenize(self, pathspec):
20        return self.sha1

还可以构造一个修改路径段的简单缓存buster:

 1import posixpath
 2
 3class PathConstantCacheBuster(object):
 4    def __init__(self, token):
 5        self.token = token
 6
 7    def __call__(self, request, subpath, kw):
 8        base_subpath, ext = posixpath.splitext(subpath)
 9        new_subpath = base_subpath + self.token + ext
10        return new_subpath, kw

这种方法的警告是,修改路径段会更改文件名,因此必须匹配文件系统上的实际内容,以便 add_static_view() 找到文件。最好使用 ManifestCacheBuster 对于这些情况,如下一节所述。

路径段和选择缓存buster

如果URL包含查询字符串,许多缓存HTTP代理将无法缓存资源。因此,一般来说,您应该更喜欢修改路径段的缓存总线策略,而不是向查询字符串添加令牌的方法。

你需要考虑 Pyramid 应用程序将为您的静态资产提供服务,无论您是否使用外部资产管道来处理CSS/javascript内部的重写URL,以及您希望缓存占用令牌的细粒度如何。

在许多情况下,您希望将静态资产托管在另一个Web服务器上或外部的cdn上。在这些情况下, Pyramid 应用程序甚至可能无法访问静态资产的副本。为了缓存这些资产,您需要一些关于它们的信息。

如果使用外部资产管道生成静态文件,则应考虑使用 ManifestCacheBuster . 这个cache-buster可以加载一个由管道生成的标准JSON格式的文件,并使用它来缓存破坏资产。这有许多性能优势,如 Pyramid 不需要查看文件来生成任何缓存占用令牌,但仍然支持每个文件的细粒度令牌。

举个例子 manifest.json 像:

{
    "css/main.css": "css/main-678b7c80.css",
    "images/background.png": "images/background-a8169106.png"
}

以下代码将设置一个cachebuster:

1from pyramid.static import ManifestCacheBuster
2
3config.add_static_view(
4    name='http://mycdn.example.com/',
5    path='mypackage:static')
6
7config.add_cache_buster(
8    'mypackage:static/',
9    ManifestCacheBuster('myapp:static/manifest.json'))

需要注意的是,高速缓存buster只处理为静态资产生成高速缓存的URL。它确实 NOT 为这些资产提供任何解决方案。例如,如果为 css/main-678b7c80.css 然后,该URL需要通过配置 add_static_view 正确地指向文件的位置或其他一些机制,例如cdn上现有的文件或重写传入的URL以删除缓存中断令牌。

CSS和JavaScript源和缓存总线

通常,我们需要引用CSS和JavaScript文件中的图像和其他静态资产。如果缓存总线处于活动状态,则在组装静态资产之前,最终的静态资产URL不可用。这些URL不能手写。下面是如何将高速缓存buster集成到整个堆栈中的示例。记住,这只是一个例子,应该修改以适合您的特定工具。

  • 首先,使用预编译程序来处理文件,该预编译程序将URL重写为最终的缓存总线形式。然后,您可以使用 ManifestCacheBuster 将资产管道与 Pyramid 允许管道完全控制资产的最终URL。

现在您可以在 Pyramid ,您需要处理超出我们控制范围的URL。为此,您可以使用以下某些选项开始:

  • 配置资产管道以在CSS和JavaScript中内联重写URL引用。这是最好的方法,因为文件可能由 Pyramid 或者一个外部的cdn,而不需要改变任何东西。它们确实是静态的。

  • 将JS和CSS模板化,并调用 request.static_url() 在他们的模板代码中。虽然这种方法可能适用于某些场景,但不建议这样做,因为您的静态资产不会真正是静态的,并且现在依赖于 Pyramid 正确送达。见 高级:使用可调用视图服务静态资产 有关此方法的详细信息。

如果您的CSS和JavaScript资产使用URL引用其他资产,建议您实现一个外部资产管道,该管道可以使用包含缓存占用令牌的新URL重写生成的静态文件。里面的机器 Pyramid 这一步没有帮助,因为它对您的应用程序可能使用的资产类型知之甚少。整合到 Pyramid 只是为了将这些资产链接到HTML和其他动态内容中。

高级:使用可调用视图服务静态资产

为了获得更大的灵活性,静态资产可以由 view callable 手动注册。例如,如果您正在使用 URL dispatch ,您可能希望静态资产仅在以前没有匹配的路由时可用作回退。或者,您可能希望手动为特定的静态资产提供服务,因为它的下载需要身份验证。

请注意,您不能使用 static_url() API针对通过注册自定义静态视图可访问的资产生成URL。

根相对自定义静态视图(仅限URL调度)

这个 pyramid.static.static_view helper类生成一个可调用的金字塔视图。此视图可调用可以为目录中的静态资产提供服务。该类的一个实例实际由 add_static_view() 配置方法,因此一旦配置它,它的行为几乎完全相同。

警告

以下示例 不会工作 对于使用 traversal ;只有当您使用 URL dispatch 专门地。我们将要注册的根相对路由将始终在进行遍历之前匹配,并通过 add_view (at least those without a route_name )一 static_view 使用遍历时,静态视图不能成为根相对视图,除非它注册为 Not Found View .

要在文件系统上的目录中提供文件,请执行以下操作: /path/to/static/dir as the result of a "catchall" route hanging from the root that exists at the end of your routing table, create an instance of the static_view 内部A类 static.py 文件在应用程序根目录中,如下所示。

1from pyramid.static import static_view
2static_view = static_view('/path/to/static/dir', use_subpath=True)

备注

要获得更好的跨系统灵活性,请使用 asset specification 作为 static_view 而不是物理绝对文件系统路径,例如, mypackage:static ,而不是 /path/to/mypackage/static .

随后,您可以将此视图提供服务的文件连接为 /<filename> 在应用程序的启动代码中使用配置方法。

1# .. every other add_route declaration should come
2# before this one, as it will, by default, catch all requests
3
4config.add_route('catchall_static', '/*subpath')
5config.add_view('myapp.static.static_view', route_name='catchall_static')

The special name *subpath above is used by the static_view 可调用视图,表示文件相对于所服务目录的路径。

注册一个可调用为“静态”资产服务的视图

您可以注册一个可调用的简单视图,以服务于单个静态资产。要做到这一点,就要“亲手”做事。首先定义视图可调用。

1import os
2from pyramid.response import FileResponse
3
4def favicon_view(request):
5    here = os.path.dirname(__file__)
6    icon = os.path.join(here, 'static', 'favicon.ico')
7    return FileResponse(icon, request=request)

上面的代码位在 favicon_view 计算“here”,它是相对于定义函数的python文件的路径。然后创建一个 pyramid.response.FileResponse 使用文件路径作为响应 path 作为响应的参数和请求 request 参数。 pyramid.response.FileResponse 以这种方式使用时,将尽快提供文件。它确保根据传递的文件扩展名设置正确的内容长度和内容类型。

您可以通过配置将此类视图注册为可调用视图,该视图应作为遍历结果调用:

1config.add_view('myapp.views.favicon_view', name='favicon.ico')

或者您可以将其注册为特定路由的可调用视图:

1config.add_route('favicon', '/favicon.ico')
2config.add_view('myapp.views.favicon_view', route_name='favicon')

因为这是一个可调用的简单视图,所以可以使用 permission 或者可以配置为在不同情况下响应,使用 view predicate 参数。

压倒一切的资产

从给定的“外部”重写特定资产通常很有用 Pyramid 应用。例如,您可能希望重用现有的 Pyramid 应用程序或多或少保持不变。但是,应用程序拥有的某些特定模板文件可能具有不适当的HTML,或者某些静态资产(例如徽标文件或某些CSS文件)可能不合适。你 能够 只需完全复刻应用程序,但通常更方便的做法是重写不适当的资产,并“按原样”重用应用程序。当您一次又一次地为一些客户(如CMS应用程序或某些错误跟踪应用程序)重用某些“核心”应用程序,并且您希望在不复刻基础代码的情况下对特定应用程序部署进行任意的可视化修改时,这一点尤其正确。

为此, Pyramid 包含使一个或多个其他资产可以“覆盖”一个资产的功能。为支持此功能,a Configurator 存在名为的API pyramid.config.Configurator.override_asset() . 此API允许您 覆盖 在任何python包中定义的以下类型的资产:

  • 单个模板文件。

  • 包含多个模板文件的目录。

  • 单个静态文件由 pyramid.static.static_view 助手类。

  • 一个静态文件目录,由 pyramid.static.static_view 助手类。

  • 由使用设置工具的代码处理的任何其他资产(或一组资产) pkg_resources 应用程序编程接口。

这个 override_asset API

个人呼叫 override_asset() 可以覆盖单个资产。例如:

1config.override_asset(
2    to_override='some.package:templates/mytemplate.pt',
3    override_with='another.package:othertemplates/anothertemplate.pt')

传递给两者的字符串值 to_overrideoverride_with 发送到 override_asset API称为 asset specification . 规范中的冒号分隔符将 包名资产名称 . 冒号和以下资产名称是可选的。如果未指定,则重写将尝试解析从另一个包的目录到包中的每次查找。例如:

1config.override_asset(to_override='some.package',
2                      override_with='another.package')

包中的各个子目录也可以重写:

1config.override_asset(to_override='some.package:templates/',
2                     override_with='another.package:othertemplates/')

如果您希望用另一个目录覆盖一个目录,您可以 must 确保将斜线连接到 to_override 规范和 override_with 规范。如果未能在指向目录的规范末尾附加斜线,将得到意外的结果。

不能用文件规范重写目录规范,反之亦然;如果尝试,将发生启动错误。不能用自身重写资产;如果尝试,将发生启动错误。

只有个人 包裹 资产可能被覆盖。重写将不会遍历重写包内的子包。这意味着,如果您想覆盖这两项的资产 some.package:templatessome.package.views:templates ,您需要注册两个覆盖。

规范中的包名称可以以点开头,这意味着包与配置构造文件所在的包(或 package 论据 Configurator 等级结构)。例如:

1config.override_asset(to_override='.subpackage:templates/',
2                      override_with='another.package:templates/')

多次呼叫 override_asset 哪个名字是共享的 to_override 但不同 override_with 规范可以“堆叠”以形成搜索路径。将使用搜索路径中存在的第一个资产;如果覆盖路径中不存在任何资产,则使用原始资产。

资产覆盖实际上可以覆盖模板和静态文件以外的资产。任何使用 pkg_resources.get_resource_filename()pkg_resources.get_resource_stream()pkg_resources.get_resource_string() 当使用重写时,API将获取重写文件。

在 1.6 版本加入: 从金字塔1.6开始,也可以通过提供文件或目录的绝对路径来覆盖资产。如果资产不是作为Python包的一部分分发的话,这可能很有用。

缓存总线和资源覆盖

重写正在使用托管的静态资产 pyramid.config.Configurator.add_static_view() 当使用任何具有资产意识的缓存buster时,可能会影响缓存占用策略,例如 pyramid.static.ManifestCacheBuster . 使资产感知缓存buster与众不同的是,它们具有与特定资产相关的逻辑。例如,仅为一组特定的预定义资产生成清单。现在,假设您已经用一个新的未知版本覆盖了清单中定义的资产。默认情况下,将为以前从未见过的资产调用高速缓存buster,并可能最终返回原始资产的高速缓存占用令牌,而不是实际提供服务的资产!为了解决这个问题,可以附加一个 pyramid.interfaces.ICacheBuster 新资产的实施。这将导致原始资产由它们的清单提供服务,新资产由它们自己的高速缓存清除器提供服务。要做到这一点, pyramid.config.Configurator.add_cache_buster() 支持一个 explicit 选择权。例如:

 1from pyramid.static import ManifestCacheBuster
 2
 3# define a static view for myapp:static assets
 4config.add_static_view('static', 'myapp:static')
 5
 6# setup a cache buster for your app based on the myapp:static assets
 7my_cb = ManifestCacheBuster('myapp:static/manifest.json')
 8config.add_cache_buster('myapp:static', my_cb)
 9
10# override an asset
11config.override_asset(
12    to_override='myapp:static/background.png',
13    override_with='theme:static/background.png')
14
15# override the cache buster for theme:static assets
16theme_cb = ManifestCacheBuster('theme:static/manifest.json')
17config.add_cache_buster('theme:static', theme_cb, explicit=True)

在上面的例子中有一个默认的高速缓存buster, my_cb ,对于 myapp:static 文件夹。这也会影响 theme:static/background.png 当通过生成URL时 request.static_url('myapp:static/background.png') .

这个 theme_cb 为从中加载的任何资产显式定义 theme:static 文件夹。显式缓存buster具有优先权,因此 theme_cb 将为调用 request.static_url('myapp:static/background.png') ,但是 my_cb 将用于任何其他资产,如 request.static_url('myapp:static/favicon.ico') .