开发者

Django caching bug .. even if caching is disabled

I have a Django site where a strange bug is occurring.

On the site they can add "publications", which is basically the same thing 开发者_如何学JAVAas a blog post under a different name.

Things gets weird when they modify an existing post. They first modify it in the admin and when they go on the site, the change isn't visible. Like if the old version was cached.

In fact, at the beginning I was pretty sure it was a browser caching bug. But after some trials, things got a little weirder.

I found out that clearing browser cache or using a different browser does not solve the problem, but rather interestingly it toggles between the old version and the modified version upon refresh.

So if the body of the post was "Hello World" and I modify it to be "Goodbye cruel world" and then go to the site and refresh the page multiple times, I would see "Hello World", then "Goodbye cruel world", then "Hello World" and so on.. no matter how long I keep doing it.

But it doesn't stop there .. after about 24h everything falls back into place and work normally. No permutation anymore, the site sticks to the new version...

I'm pretty much speechless because I built well over 50 other Django sites using the same server and I never had this problem before.

I'm using the latest django (1.3) with a MySQL DB and caching is not enabled..

Any ideas ?

Edit: A graceful restart of Apache solve the problem .. but restarting apache after each update isn't the greatest thing..

Update: I've just re-setuped my dev environement and I found out the bug is far more acute with the dev server. The modified contend won't show up until I kill/restart the dev server, no matter how often I refresh or clear my cache..


The problem is explicitly addressed in the generic views documentation. The querysets in your extra_context dictionary are evaluated once, when the urlconf is first processed, and each time after that they will continue to use the same values. That's why they only change when you reset Apache or the dev server.

The solution, as described on the linked page, is to use callables which return the querysets, rather than specifying the querysets in the dictionary itself.


I had a similar problem once. It turned out I created the object at the top of the urls.py, and the object was alive as long as the process was alive. You may be using a global variable in one of your views.


There are a few other ways to control cache parameters. For example, HTTP allows applications to do the following:

Define the maximum time a page should be cached.Specify whether a cache should always check for newer versions, only delivering the cached content when there are no changes. (Some caches might deliver cached content even if the server page changed, simply because the cache copy isn't yet expired.**)

In Django, use the cache_control view decorator to specify these cache parameters. In this example, cache_control tells caches to revalidate the cache on every access and to store cached versions for, at most, 3,600 seconds:

from django.views.decorators.cache import cache_control

@cache_control(must_revalidate=True, max_age=3600)
def my_view(request):
    # ...

Any valid Cache-Control HTTP directive is valid in cache_control(). Here's a full list:

public=True
private=True
no_cache=True
no_transform=True
must_revalidate=True
proxy_revalidate=True
max_age=num_seconds
s_maxage=num_seconds
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜