跳转到主要内容

Django模板片段缓存的直接替换。提供自动缓存失效功能。

项目描述

注意

https://github.com/hedleyroos/django-ultracache 是项目的官方主页。它已从https://github.com/praekelt/django-ultracache 移动。

Django Ultracache

缓存视图、模板片段和任意Python代码。监视Django对象更改,从Django级别,通过代理,到浏览器,执行自动细粒度缓存失效。

Travis

概述

缓存视图、模板片段和任意Python代码。一旦缓存,我们就可以根据用例避免数据库查询和昂贵的计算。在所有情况下,当对象“红”或“蓝”被修改时,受影响的缓存将自动过期,我们无需显式使缓存意识到“红”或“蓝”。

视图

from ultracache.decorators import ultracache

# The decorator with no parameters automatically caches on the request path
# and a minimal
# set of hidden parameters.
@ultracache(300)
class MyView(TemplateView):
    template_name = "my_view.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # The URL that was called is eg. http://mysite.com/myview/blue.
        # This view remains cached until "blue" is modified by any other
        # code.
        context["color"] = Color.objects.get(slug=kwargs["color_slug"])

        # Retrieve "red". Even though we never use red further in this code
        # the cached view is still expired when red is modified by any
        # other code.
        red = Color.objects.get(slug="red")

        return context

模板

{# variable "color" is the object "blue" #}
{% load ultracache_tags %}
{% ultracache 300 "color-info" color.pk %}
    {# expensive properties follow #}
    {{ color.compute_valid_hex_codes }}
    {{ color.name_in_all_languages }}
{% endultracache %}

任意Python

from ultracache.utils import Ultracache

...

color_slug = request.GET["color_slug"]
uc = Ultracache(300, "another-identifier", color_slug)
if uc:
    codes = uc.cached
else:
    color = Color.objects.get(slug=color_slug)
    codes = color.compute_valid_hex_codes()
    uc.cache(codes)
print(codes)

具有更具体规则的视图

from ultracache.decorators import ultracache

# Serve different cached versions for anonymous and authenticated users. "request"
# is always in scope in the decorator.
@ultracache(300, "request.user.is_authenticated")
class MyView(TemplateView):
    template_name = "my_view.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["show_private_messages"] = self.request.user.is_authenticated
        return context

安装

  1. django-ultracache 安装或添加到您的Python路径。

  2. ultracache 添加到您的 INSTALLED_APPS 设置。

  3. ultracache.middleware.UltraCacheMiddleware 添加到您的 MIDDLEWARE 设置。建议将其添加为第一个条目之一。

  4. 确保 django.template.context_processors.request 在上下文处理器设置中。

功能

  1. 缓存模板片段、视图、Django Rest Framework视图集。

  2. 它考虑了站点框架,允许每个站点进行不同的缓存。

  3. 关键的是,它知道受其缓存影响的模型对象。当一个对象被修改时,所有受影响的缓存键都会自动过期。这使用户可以设置较长的过期时间,而不必担心过期的内容。

  4. 缓存失效可以扩展到向Varnish、Nginx或其他反向缓存代理发出清除命令。

用法

cached_getultracache 视图装饰器

django-ultracache 还提供了装饰器 cached_getultracache 来缓存您的视图。参数遵循与 ultracache 模板标签相同的规则,但它们都必须解析。 request.get_full_path() 总是隐式添加到缓存键中。 ultracache 装饰器较新且更简洁,因此尽可能使用它。

from ultracache.decorators import cached_get, ultracache


class CachedView(TemplateView):
    template_name = "cached_view.html"

    @cached_get(300, "request.is_secure()", 456)
    def get(self, *args, **kwargs):
        return super(CachedView, self).get(*args, **kwargs)

@ultracache(300, "request.is_secure()", 456)
class AnotherCachedView(TemplateView):
    template_name = "cached_view.html"

cached_get 装饰器可以用于URL模式

from ultracache.decorators import cached_get

url(
    r"^cached-view/$",
    cached_get(3600)(TemplateView.as_view(
        template_name="myproduct/template.html"
    )),
    name="cached-view"
)

不要随意使用装饰器。它们只对GET请求进行操作,但无法知道被包装的代码是否从会话中检索数据。在这种情况下,它们会缓存不应缓存的内容。

如果您的视图被多个URL模式使用,则强烈建议在URL模式中应用 cached_get 装饰器。直接将其应用于 get 方法可能会导致缓存冲突,尤其是在重写 get_template_names 时。

ultracache 模板标签

django-ultracache 提供了一个模板标签 {% ultracache %},其功能类似于Django的标准缓存模板标签;然而,它考虑了站点框架,允许每个站点进行不同的缓存,并且它可以处理未定义的变量。

最简单的用法

{% load ultracache_tags %}
{% ultracache 3600 "my_identifier" object 123 undefined "string" %}
    {{ object.title }}
{% endultracache %}

标签可以嵌套。 ultracache 知道所有受其缓存影响的模型对象。在这个例子中,当对象一被更改时,缓存键 outerinner_one 会过期,但缓存键 inner_two 则不受影响。

{% load ultracache_tags %}
{% ultracache 1200 "outer" %}
    {% ultracache 1200 "inner_one" %}
        title = {{ one.title }}
    {% endultracache %}
    {% ultracache 1200 "inner_two" %}
        title = {{ two.title }}
    {% endultracache %}
{% endultracache %}

指定一个好的缓存键

缓存键决定是否对代码或模板进行进一步评估。因此,缓存键必须准确地以最小的方式描述要缓存的内容。

待办事项

Django Rest Framework视图集缓存

在视图集上缓存 listretrieve 操作

# Cache all viewsets
ULTRACACHE = {
    "drf": {"viewsets": {"*": {}}}

}

# Cache a specific viewset by name
ULTRACACHE = {
    "drf": {"viewsets": {"my.app.MyViewset": {}}}

}

# Cache a specific viewset by class
ULTRACACHE = {
    "drf": {"viewsets": {MyViewset: {}}}

}

# Timeouts default to 300 seconds
ULTRACACHE = {
    "drf": {"viewsets": {"*": {"timeout": 1200}}}

}

# Evaluate code to append to the cache key. This example caches differently
# depending on whether the user is logged in or not.
ULTRACACHE = {
    "drf": {"viewsets": {"*": {"evaluate": "request.user.is_anonymous"}}}

}

# Evaluate code to append to the cache key via a callable.
def mycallable(viewset, request):
    if viewset.__class__.__name__ == "foo":
        return request.user.id

ULTRACACHE = {
    "drf": {"viewsets": {"*": {"evaluate": mycallable}}}

}

清除器

您可以创建自定义反向缓存代理清除器。请参阅 purgers.py 中的示例

ULTRACACHE = {
    "purge": {"method": "myproduct.purgers.squid"}
}

最有用的清除器是 broadcast。如名称所示,它将清除指令广播到队列中。请注意,您需要运行celery并配置为将数据写入RabbitMQ实例,才能正确工作。

清除指令由 cache-purge-consumer.py 脚本消耗。该脚本从队列中读取清除指令,然后将清除指令发送到相关的反向缓存代理。要运行脚本

virtualenv ve
./ve/bin/pip install -e .
./ve/bin/python bin/cache-purge-consumer.py -c config.yaml

配置文件有以下选项

  1. rabbit-url
    以AMQP URL格式指定RabbitMQ连接参数 amqp://username:password@host:port/<virtual_host>[?query-string]
    可选。默认为amqp://guest:guest@127.0.0.1:5672/%2F。注意路径的URL编码。
  2. host
    反向缓存代理可能负责许多域名(主机),ultracache 将跟踪涉及清除请求的主机;但是,如果您有不需要主机名的用例,例如通过curl执行 PURGE 请求,则强制主机名可以解决此问题。
    可选。
  3. proxy-address
    反向缓存代理的IP地址或主机名。
    可选。默认为 127.0.0.1。
  4. logfile
    将日志记录所有清除指令设置到文件中。指定stdout以将日志记录到标准输出。
    可选。

其他设置

自动失效默认为开启。要禁用自动失效,设置

ULTRACACHE = {
    "invalidate": False
}

django-ultracache在Django的缓存后端中维护一个注册表(见《如何工作》)。这个注册表不能无限制地增长,因此对注册表的大小进行了限制。在整个注册表中设置大小限制是不高效的,因此为每个缓存值设置最大大小。默认为1000000字节

ULTRACACHE = {
    "max-registry-value-size": 10000
}

强烈建议使用支持压缩的后端,因为更大的大小可以改善缓存一致性。

如果您使用反向缓存代理,则需要原始请求头(或相关子集)来从代理中正确清除路径。现代网络的问题在于每个请求上都有大量的请求头,这将导致django-ultracache在Django的缓存后端中存储大量条目。您的代理可能有一个自定义的哈希计算规则,该规则只考虑请求路径(始终暗示)和Django的sessionidcookie,因此定义一个设置,也只考虑Django侧的cookie

ULTRACACHE = {
    "consider-headers": ["cookie"]
}

如果您只需要考虑一些cookie,则设置

ULTRACACHE = {
    "consider-cookies": ["sessionid", "some-other-cookie"]
}

它是如何工作的?

django-ultracache通过修改django.template.base.Variable._resolve_lookupdjango.db.models.Model.__getattribute__来记录在解析时模型对象的记录。模板标签、装饰器和上下文管理器检查它们包含的对象列表,并在Django的缓存后端中保持注册表。一个信号处理器监视对象的变化并使相应的缓存键过期。

技巧

  1. 如果您运行一组Django节点,请确保它们使用共享缓存后端。

作者

  • Hedley Roos

变更日志

2.2

  1. Django 4.0兼容性。

2.1.1

  1. 确保清除器失败时缓存一致性。

2.1.0

  1. Django 3兼容性。

  2. 修复潜在的线程局部残留数据问题。

2.0.0

  1. 在所有地方删除对站点框架的依赖。如果安装了应用程序,站点框架仍然会自动考虑。

  2. 不再在请求中存储元数据,而是在线程局部列表中。

  3. 引入类utils.Ultracache,将任意Python代码块提交给缓存。

  4. 停止对Django 1的支持。

1.11.12

  1. 更简单的基于类的装饰器。

  2. 添加Django 2.1和Python 3.6测试。

1.11.11

  1. 添加任务测试。

1.11.10

  1. 如果找不到pika,则明确抛出异常。

  2. cached_get现在考虑在get_context_data中访问的任何对象,而不仅仅是视图模板中访问的对象。

  3. 现在将原始请求头与路径一起发送到清除器。这可以实现细粒度的代理失效。

  4. Django 2.0和Python 3兼容性。已删除Django 1.9支持。

1.11.9

  1. 简化DRF缓存实现。它现在还考虑了子序列化器接触到的对象。

1.11.8

  1. DRF设置现在接受点分名称。

  2. DRF设置现在接受一个可调用对象,其结果构成了缓存键的一部分。

1.11.7

  1. 使用pickle缓存DRF数据,因为DRF使用Python的json库不识别的Decimal类型。

1.11.6

  1. 调整DRF装饰器,使其可以在更多地方使用。

1.11.5

  1. Django Rest Framework缓存不再缓存整个响应,而只缓存数据和头。

1.11.4

  1. 将twisted工作移至django-ultracache-twisted

  2. 如果找不到库,则明确抛出异常。

1.11.3

  1. 将twisted目录向下移动一个级别。

1.11.2

  1. 正确打包产品,以便包括所有目录。

1.11.1

  1. 引入更多防御性代码,以确保在测试运行中的迁移期间不干扰。

1.11.0

  1. broadcast_purge任务引入rabbitmq-url设置。

  2. Django 1.11支持。

  3. 弃用Django 1.6支持。

1.10.2

  1. 移除依赖于 SITE_ID 的逻辑,以便可以从请求中推断出站点。

1.10.1

  1. 为 Django Rest Framework 视图集添加缓存。

  2. 与 Django 1.10 兼容。

1.9.1

  1. 添加缺失的导入,仅在特定代码路径中暴露。

  2. Invalidatesetting 设置未正确加载。已修复。

  3. 处理内容类型尚未迁移时的 RuntimeError。

1.9.0

  1. 将测试移至 tox。

  2. 与 Django 1.9 兼容。

0.3.8

  1. 尊重 loaddata 发送的 raw 参数。它防止了冗余的 post_save 处理。

0.3.7

  1. 撤销添加模板名称。它在 WSGI 环境中引入了性能惩罚。

  2. 进一步减少对缓存的写入次数。

0.3.6

  1. (如果可能)将模板名称添加到缓存键中。

  2. 减少对 set_many 的调用次数。

0.3.5

  1. 检查元数据缓存大小,以防止无限增长。

0.3.4

  1. 防止重复设置。

  2. 解决与 di[k].append(v)di[k] = di[k] + [v] 相关的明显 Python 错误。后者是安全的。

0.3.3

  1. 处理一个缓存的视图在内部渲染另一个缓存的视图的情况,从而可能共享相同的缓存键。

0.3.2

  1. ultracache 模板标记现在仅缓存 HEAD 和 GET 请求。

0.3.1

  1. 为解决当天 PyPi 错误而发布的简单版本。

0.3

  1. 将循环中的 cache.get 替换为 cache.get_many

0.2

  1. 如果 request.get_full_path()request.pathrequest.path_info 中的任何一个参数是 cached_get 的参数,则不要自动添加 request.get_full_path()

0.1.6

  1. 也缓存响应头。

0.1.5

  1. 显式检查 GET 和 HEAD 请求方法,并仅缓存这些请求。

0.1.4

  1. 将装饰器重写为基于函数的,而不是基于类的,以便在 urls.py 中更容易使用。

0.1.3

  1. cached_get 装饰器现在如果请求包含消息则不缓存。

0.1.2

  1. 修复 HTTPResponse 缓存错误。

0.1.1

  1. 处理视图返回 HTTPResponse 对象的情况。

0.1

  1. 首次发布。

项目详情


下载文件

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

源分布

django-ultracache-2.2.tar.gz (59.6 kB 查看哈希)

上传时间

构建分布

django_ultracache-2.2-py3.6.egg (119.4 kB 查看哈希)

上传时间

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面