【问题标题】:Disable caching for a view or url in django在 django 中禁用视图或 url 的缓存
【发布时间】:2011-04-12 11:23:29
【问题描述】:

在 django 中,我编写了一个仅返回文件的视图,但现在我遇到了问题,因为 memcache 正在尝试缓存该视图,换句话说,“TypeError: can't pickle file objects”。

因为我确实需要用这个视图返回文件(我基本上已经为这个视图创建了一个基于文件的缓存),我需要做的就是以某种方式使它无法或不会尝试缓存视图。

我认为这可以通过两种方式完成。首先,阻止视图被缓存(装饰器在这里很有意义),其次,阻止 URL 被缓存。

似乎都不可能,而且似乎没有其他人遇到过这个问题,至少在公共互联网上没有。帮助?

更新:我已经尝试过 @never_cache 装饰器,甚至认为它可以工作,但是虽然它设置了标题,所以 其他 人不会缓存东西,我的本地机器仍然可以。

【问题讨论】:

    标签: django caching


    【解决方案1】:
    from django.views.decorators.cache import never_cache
    
    @never_cache
    def myview(request):
        # ...
    

    Documentation在这里...

    【讨论】:

    • 这使 其他 计算机无法缓存内容,但我本地安装的 memcached 仍然缓存内容...令人沮丧。
    • 如果你问的是标准的 Django 缓存中间件,这个答案是正确的。 Django 缓存框架由标准 HTTP Cache-Control 标头控制,类似于 @never_cache 装饰器设置的标头。
    • 很高兴知道。显然,我真的很难知道是否有东西被缓存了。
    【解决方案2】:

    从视图返回一个真实的、实际的文件对象听起来有些不对劲。我可以看到返回文件的内容,将这些内容输入到 HttpResponse 对象中。如果我理解正确,您正在将此视图的结果缓存到文件中。像这样的:

    def myview(request):
        file = open('somefile.txt','r')
        return file    # This isn't gonna work. You need to return an HttpRequest object.
    

    我猜如果你在 settings.py 中完全关闭缓存,你的“不能腌制文件对象”会变成“视图必须返回一个 http 响应对象”。

    如果我对正在发生的事情走在正确的轨道上,那么这里有几个想法。

    您提到您正在为这一视图制作基于文件的缓存。您确定要这样做而不是只使用 memcached?

    如果你真的想要一个文件,那么就这样做吧:

    def myview(request):
        file = open('somefile.txt','r')
        contents = file.read()
        resp = HttpRespnse()
        resp.write(contents)
        file.close()
        return resp
    

    这将解决您的“无法腌制文件”问题。

    【讨论】:

    • 感谢周到的 cmets。是的,我基本上按照你的建议去做。我不使用 memcached 的原因是因为它用于站点上的站点地图,生成(大约)需要 20 秒,并且会很快填满 memcached(我有大约 600 个站点地图)。通过使用自主开发的基于文件的缓存,它们会生成一次,然后始终如一地提供服务。如果他们改变了(他们通常不会),我只是手动从磁盘中删除文件,一切都很好!
    • 令人惊讶的是,这最终是答案。我以为我的缓存工作正常,但我错过了它试图简单地返回文件的一个区域。啊!感谢赏金。
    【解决方案3】:

    您可能执行了per site cache,但您现在想做的是per view cache。第一个更容易实现,但仅适用于“仅缓存所有内容”的情况。因为您现在想为每个视图进行选择,所以只需切换到细粒度方法。它也非常易于使用,但请记住,有时您需要创建具有相同内容的第二个视图,如果您想让结果有时缓存有时不缓存,具体取决于 url。

    到目前为止,您的问题的答案。但这是你问题的答案吗?为什么要在视图中返回文件?通常静态文件,如视频、图片、css、flash 游戏或任何应该由服务器本身(甚至由不同的服务器)处理的文件。我想,这就是你想要在那个视图中做的事情。那是对的吗?之所以不让 django 做这件事,是因为启动 django 让 django 做它的事情,也需要耗费大量的资源和时间。当您是测试环境中的唯一用户时,您不会有这种感觉。但是当你想扩展到几千个或更多用户时,这种东西就变得非常讨厌了。同样从逻辑的角度来看,当程序的正常工作是根据数据状态和用户请求生成或更改 HTML 时,让程序在不更改文件的情况下处理文件似乎并不明智。这就像让你的会计师做编程工作。虽然他可能会做,但您可能希望其他人做这件事,让会计师来处理您的账簿。

    【讨论】:

    • 非常完整的答案,但我这样做的原因是在站点的站点地图上实现基于文件的缓存,并在其他任何地方实现 memcached 缓存。烦人的是,我自己做的唯一方法是让我的 600 多个站点地图始终不填满缓存,同时保持良好的响应率!
    猜你喜欢
    • 2017-04-28
    • 2010-12-08
    • 2012-10-15
    • 2021-08-09
    • 1970-01-01
    • 2011-12-12
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多