我最近实现了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's vary headers的信息,但它有点过头了,我甚至不确定它是否是正确的解决方案
答案 0 :(得分:16)
是的,不同的标题不是正确的解决方案,当您想根据客户端请求标头(如用户代理等)进行缓存时使用它。
您需要使用low-level API或template fragment caching。这取决于你的观点。
使用低级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
...
..
.
答案 1 :(得分:8)
是的,您可以使用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):
...
答案 2 :(得分:4)
这应该不再是Django 1.3+中的一个问题。 请参阅:https://docs.djangoproject.com/en/dev/topics/cache/#using-vary-headers
答案 3 :(得分:3)
您似乎不再需要做任何比将@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(...)
答案 4 :(得分:1)
根据我对源代码和经验测试的阅读,@cache_page
装饰器可以正确地本地处理GET
参数(至少在Django 2.2中如此)。
浏览源:
django.views.decorators.cache
django.utils.decorators.decorator_from_middleware_with_args()
django.utils.decorators.make_middleware_decorator()
的人middleware.process_request()
,其中“中间件”是django.middleware.cache.CacheMiddleware
。django.utils.cache.get_cache_key()
来生成缓存密钥。django.utils.cache._generate_cache_header_key()
的人。request.build_absolute_uri()
,其中“请求”为django.http.request.HttpRequest
django.http.request.HttpRequest.get_full_path()
的人django.http.request.HttpRequest._get_full_path()
的人self.META.get('QUERY_STRING', '')
。另一方面,当响应完成时,类似的路径会通过middleware.process_response()
,最终会调用django.utils.cache._generate_cache_header_key()
来确定将响应存储在缓存中的位置。
从经验上,我可以看到对装饰视图的请求正在缓存,并且当GET参数更改时响应也会更改。
答案 5 :(得分:0)
有点晚了,但你可以使用django-view-cache-utils。