繁体   English   中英

缓存具有URL参数的django视图

[英]Cache a django view that has URL parameters

我最近实现了Django优秀的缓存框架。 但是根据我的理解,Django不会缓存在get请求中传递参数的视图。 我有一个Ajax视图,传递get参数,我想缓存X秒,这是一个简单的方法吗?

在psuedo代码中,我目前有一个URL:

http://mysites/ajaxthing/?user=foo&items=10

我想缓存任何这个url,只要它具有相同的get参数。

我目前在我的视图中使用缓存装饰器:

myview(stuff)

myview = cache_page(myview, 60 * 3)

我确实读过关于django的各种标题,但它有点过头了,我甚至不确定它是否是正确的解决方案

是的,不同的标头不是正确的解决方案,当你想根据客户端请求标头(如用户代理等)进行缓存时使用它。

您需要使用低级API模板片段缓存 这取决于你的观点。

使用低级API,它看起来像这样:

from django.core.cache import cache

def get_user(request):
    user_id = request.GET.get("user_id")
    user = cache.get("user_id_%s"%user_id)
    if user is None:
        user = User.objects.get(pk=user_id)
        cache.set("user_id_%s"%user_id, user, 10*60) # 10 minutes
    ...
    ..
    .

是的,您可以使用django-view-cache-utils,这里是您的案例的代码:

from view_cache_utils import cache_page_with_prefix
from django.utils.hashcompat import md5_constructor
...
@cache_page_with_prefix(60*15, lambda request: md5_constructor(request.get_full_path()).hexdigest())
def my_view(request):
    ...

这应该不再是Django 1.3+中的问题。 请参阅: https//docs.djangoproject.com/en/dev/topics/cache/#using-vary-headers

看起来您不再需要做任何比将@cache_page([时间长度])放在您尝试缓存的View函数上方更复杂的事情,无论您是否在URL中有参数。

例如,如果你有一个像这样的网址:

http://example.com/user/some_user_id

views.py中的视图函数如下所示:

from django.views.decorators.cache import cache_page
...

@cache_page(60 * 10)
def get_user_detail(request, user_id=None):
    ...
    return render(...)

有点晚了,但你可以使用django-view-cache-utils

从我对源代码和经验测试的阅读中, @cache_page装饰器本身正确处理GET参数(至少在Django 2.2中)。

挖掘来源:

  1. 装饰器在django.views.decorators.cache定义
  2. 它调用django.utils.decorators.decorator_from_middleware_with_args()
  3. 哪个调用django.utils.decorators.make_middleware_decorator()
  4. 这是一个愚蠢的复杂程度。 一个名副其实的功能洋葱功能。 重要的是调用middleware.process_request() ,其中'middleware'是django.middleware.cache.CacheMiddleware
  5. 其中调用django.utils.cache.get_cache_key()来生成缓存键。
  6. 其中调用django.utils.cache._generate_cache_header_key()
  7. 哪个调用request.build_absolute_uri() ,其中'request'是django.http.request.HttpRequest
  8. 哪个调用django.http.request.HttpRequest.get_full_path()
  9. 哪个调用django.http.request.HttpRequest._get_full_path()
  10. 最后,它返回的字符串中包含self.META.get('QUERY_STRING', '')

另一方面,当响应完成时,类似的路径通过middleware.process_response() ,它最终调用django.utils.cache._generate_cache_header_key()来确定将响应存储在缓存中的位置。

根据经验,我可以看到正在缓存对装饰视图的请求,并且当GET参数更改时响应会发生变化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM