6

我遵循了堆栈溢出链接中提供的解决方案,当我从浏览器中使用它时,它运行良好。但是,当我尝试使用 curl 访问该 url 时,它不会为浏览器缓存..

让我解释。

如果我example.org/results?limit=7从我的 chrome 中点击一个 url,它需要8-10 seconds加载并且连续点击需要时间 milliseconds

所以我所做的就是URLcurl命令调用它;但它没有使用缓存的数据并再次创建了缓存。

所以我发现问题出arg在下面代码中的参数上,因为它包含对象中的浏览器标头,该WSGIRequest对象用于缓存键,因为它还包含我不需要缓存的标头。这没有达到我的 curl 请求自动创建缓存的目的celery task

@method_decorator(cache_page(60 * 60 * 24))
def dispatch(self, *arg, **kwargs):
    print(arg)
    print(kwargs)
    return super(ProfileLikeHistoryApi, self).dispatch(*arg, **kwargs)  

我能做的就是只传递kwargs创建缓存或任何其他替代方法,我可以通过这些替代方法只缓存 url 而不是标题

我在这里先向您的帮助表示感谢。

4

1 回答 1

3

TLDR;手动删除方法装饰器和缓存

from django.core.cache import cache
from django.utils.encoding import force_bytes, force_text, iri_to_uri
import hashlib

def dispatch(self, *arg, **kwargs):

    if self.request.method == 'GET' or self.request.method == 'HEAD':
        key = hashlib.md5(force_bytes(iri_to_uri(self.request.build_absolute_uri()))))
        data = cache.get(key)
        if not data:
            data = super(ProfileLikeHistoryApi, self).dispatch(*arg, **kwargs)  
            cache.set(key, data, 60*60*24)
            return data

   return super(ProfileLikeHistoryApi, self).dispatch(*arg, **kwargs)  

cache_page 装饰器

是的,你是对的,缓存页面装饰器将根据标题决定缓存什么。然而,只有“变化”标题应该有影响。

其次,只有 GET 和 HEAD 请求被缓存(并且可缓存),这就是为什么在上面的代码中我们首先检查方法。

md5

您可能听说过它已过时且不安全。对于密码学来说可能是这样,但它不适用于我们的案例。这里使用的哈希生成方案与 django 的_generate_cache_key使用的完全相同,但我们从等式中省略了标题。

那个人得到的页面很慢

每天都会有一个人因为缓存过期而得到一个缓慢的页面。其他人都会得到陈旧的数据。长达 23 小时 59 分钟的数据。

考虑运行后台进程或在后台运行此任务的 cron,例如每 6 小时并刷新缓存。

现在使用 memcached 可能有点困难,因为它没有提供一种简单的方法来查找具有特定模式的所有键,但是如果您使用 redis 或缓存在数据库中,它就会变得容易。

于 2017-06-08T12:22:32.847 回答