python – 来自Django Cache的TypeError

更新:请参阅下面的“更好的解决方案”.

这个让我难过.当我调用由Django REST Framework生成的HTML页面时,它可以工作.当我把它称为第二,第三,第四次时,我得到:

[26/Oct/2015 15:14:42]"GET /api/rest/v3/dockets/ HTTP/1.1" 500 92424
Internal Server Error: /api/rest/v3/dockets/
Traceback (most recent call last):
  File "/home/mlissner/.virtualenvs/courtlistener/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 108, in get_response
    response = middleware_method(request)
  File "/home/mlissner/.virtualenvs/courtlistener/local/lib/python2.7/site-packages/django/middleware/cache.py", line 134, in process_request
    response = self.cache.get(cache_key, None)
  File "/home/mlissner/.virtualenvs/courtlistener/local/lib/python2.7/site-packages/django/core/cache/backends/locmem.py", line 54, in get
    return pickle.loads(pickled)
TypeError: __new__() takes exactly 3 arguments (2 given)

与我从Django获得的99%的堆栈跟踪不同,这个跟踪根本没有提到我的代码,而且似乎只是来自Django本身的代码.

我正在使用开发服务器,Django 1.8.7,Django REST Framework 3.2.3和Python 2.7.

我的中间件设置是:

MIDDLEWARE_CLASSES = [
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware',
]

我在浏览Django REST Framework页面时才看到这个.有任何想法吗?

我试过的事情

>升级Django,djangorestframework和djangorestframework-filters.
>更改我的CACHE设置,使其使用Redis而不是LocMemCache.我认为这可能有所帮助,因为评论中有人说将其更改为FileBasedCache有帮助.对Redis的更改本身并没有帮助,尽管将其设置为DummyCache.

django-redis-cache允许你设置不同版本的泡菜,所以我已经修改了它,因为one link暗示了泡菜版本是相关的.起初,这似乎没有任何效果,但I filed a bug在django-redis(“PICKLE_VERSION似乎不起作用”),他们很快就修复了.一旦修复,我将PICKLE_VERSION设置为1,问题就解决了.

我也是filed a bug in DRF,看看是否有更好的方法来深究这一点.但是,我不确定错误是在那里,在我的代码中,还是在Django本身.

更好的解决方案

看来,我是解决方法的主人.但好消息是,这是bug在Django Rest Framework中有been fixed,并将在3.3.2中发布(希望如此).

最佳答案 很容易理解为什么只有在第二次访问页面后才会出现问题.这是因为当您第一次加载页面时,数据从数据源(数据库?)中获取,并写入缓存.之后,每个页面加载将直接命中缓存.

似乎问题与缓存的数据类型有关.在pickle模块中引发异常,当从字符串加载缓存数据时,unpickler错误地检测数据类型,并调用该类的__new__方法.这就是错误发生的地方.

有一些帖子谈论pickle卸载错误,看看它们是否有帮助:

> http://bugs.python.org/issue3065
> http://www.gossamer-threads.com/lists/python/python/373825

它看起来在挑选元组时存在问题,你的应用程序中缓存的数据是否包含元组?

点赞