【问题标题】:TypeError from Django Cache来自 Django 缓存的 TypeError
【发布时间】:2015-10-26 22:23:41
【问题描述】:

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

这个让我难过。当我调用由 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 框架页面时看到过这一点。有什么想法吗?

我尝试过的事情

  • 正在升级 Django、djangorestframework 和 djangorestframework-filters。
  • 更改我的CACHE 设置,使其使用Redis 而不是LocMemCache。我认为这可能会有所帮助,因为 cmets 中有人说将其更改为 FileBasedCache 有帮助。尽管将其设置为 DummyCache,但对 redis 的更改本身并没有帮助。

解决方案

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

我也filed a bug in DRF 看看是否有更好的方法来解决这个问题。但是,我不确定该错误是否存在,在我的代码中,还是在 Django 本身中。

更好的解决方案

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

【问题讨论】:

  • Django 和 DRF 的版本?你在使用 django-extensions 吗?你能发布你的settings.CACHE 吗?
  • @sax:用这些细节更新了 Q,感谢您的帮助!
  • @sax:settings.CACHE我没有改,所以我想它是未设置的?
  • 不确定这是否有帮助,我在 CACHE LocMemCache 遇到了同样的问题,当我搬到 FileBasedCache 时,所有问题都消失了。不知道为什么,这不是答案,仅供参考。
  • 呃。这很奇怪,@sax。我在搜索时找不到任何其他实例。你有相同的 Django、REST 框架、Python 堆栈吗?

标签: python django django-rest-framework pickle


【解决方案1】:

很容易理解为什么您的问题仅在第二次访问该页面时才会出现。那是因为当您第一次加载页面时,数据是从数据源(数据库?)中获取的,并写入缓存。之后,每次页面加载都会直接命中缓存。

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

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

pickling tuple 时似乎有问题,您的应用中缓存的数据是否包含 tuple?

【讨论】:

    【解决方案2】:

    This was a bug in Django Rest Framework,已修复,3.3.2发布。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-16
      • 2012-09-08
      • 2017-08-17
      • 2017-12-29
      • 2017-05-09
      • 1970-01-01
      • 2013-08-30
      • 2010-09-23
      相关资源
      最近更新 更多