1

我最近将我的 1.4 项目升级到 1.6,在解决了一些弃用问题后,我遇到了另一个我无法解决的问题。

每次我尝试保存新对象或编辑现有对象时都会list index out of range出错。我理解错误的含义,但不知道 django 如何设置obj应该在obj[3]回溯将我发送到此处的值的值:django/contrib/messages/storage/cookie.py in process_messages, line 38

完整追溯:

   Traceback:
File "/Users/user/Development/virtual_environments/demo/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  201.                 response = middleware_method(request, response)
File "/Users/user/Development/virtual_environments/demo/lib/python2.7/site-packages/django/contrib/messages/middleware.py" in process_response
  23.             unstored_messages = request._messages.update(response)
File "/Users/user/Development/virtual_environments/demo/lib/python2.7/site-packages/django/contrib/messages/storage/base.py" in update
  140.             messages = self._loaded_messages + self._queued_messages
File "/Users/user/Development/virtual_environments/demo/lib/python2.7/site-packages/django/contrib/messages/storage/base.py" in _loaded_messages
  91.             messages, all_retrieved = self._get()
File "/Users/user/Development/virtual_environments/demo/lib/python2.7/site-packages/django/contrib/messages/storage/fallback.py" in _get
  24.             messages, all_retrieved = storage._get()
File "/Users/user/Development/virtual_environments/demo/lib/python2.7/site-packages/django/contrib/messages/storage/cookie.py" in _get
  70.         messages = self._decode(data)
File "/Users/user/Development/virtual_environments/demo/lib/python2.7/site-packages/django/contrib/messages/storage/cookie.py" in _decode
  154.                     return json.loads(value, cls=MessageDecoder)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py" in loads
  339.     return cls(encoding=encoding, **kw).decode(s)
File "/Users/user/Development/virtual_environments/demo/lib/python2.7/site-packages/django/contrib/messages/storage/cookie.py" in decode
  49.         return self.process_messages(decoded)
File "/Users/user/Development/virtual_environments/demo/lib/python2.7/site-packages/django/contrib/messages/storage/cookie.py" in process_messages
  41.             return [self.process_messages(item) for item in obj]
File "/Users/user/Development/virtual_environments/demo/lib/python2.7/site-packages/django/contrib/messages/storage/cookie.py" in process_messages
  38.                     print 'OBJECT 3: {0}'.format(obj[3])

来自 cookies.py 的代码。问题在于尝试获取obj[3] obj 的值是:[u'__json_message', 20, u'The Player "Goodman" was changed successfully.']

class MessageDecoder(json.JSONDecoder):                            
    """                                                            
    Decodes JSON that includes serialized ``Message`` instances.   
    """                                                            

    def process_messages(self, obj):                               
        if isinstance(obj, list) and obj:                          
            if obj[0] == MessageEncoder.message_key:               
                if obj[1]:                                         
                    print obj                                      
                    print 'OBJECT 3: {0}'.format(obj[3])           
                    obj[3] = mark_safe(obj[3])                     
                return Message(*obj[2:])                           
            return [self.process_messages(item) for item in obj]   
        if isinstance(obj, dict):                                  
            return dict([(key, self.process_messages(value))       
                         for key, value in six.iteritems(obj)])    
        return obj                                                 

    def decode(self, s, **kwargs):                                 
        decoded = super(MessageDecoder, self).decode(s, **kwargs)  
        return self.process_messages(decoded)                      
4

1 回答 1

1

该错误是由“消息”cookie 格式的更改引起的,导致 Django 1.6 无法反序列化 Django 1.4 消息 cookie。

Django 1.5 包含一个修复程序,使其支持这两种格式,但这个修复程序(尚未)出现在 Django 1.6 中。

我已经为此报告了一个问题

同时,您可以使用以下中间件来删除旧格式的 cookie:

from django.contrib.messages.storage.cookie import CookieStorage
class FixMessageMiddleware(object):
    """
        The message cookie format has changed from Django 1.4 to
        Django 1.5. Django 1.5 probably supported both formats,
        but if you move from 1.4.x to 1.6.x directly, you will run into
        an IndexError:

        Exception Type: IndexError
        Exception Value:
        list index out of range
        Exception Location: (...) django/contrib/messages/storage/cookie.py in process_messages, line 37

        This small piece of middleware will track those cookies and destroy
        them (leaving new-style in tact)

        https://code.djangoproject.com/ticket/22426

        DISCLAIMER:
        This middleware will not attempt to rewrite the messages! You may
        miss important notifications because of this!
    """
    def process_request(self, request):
        data = request.COOKIES.get("messages")
        storage = CookieStorage(request)
        try:
            storage._decode(data)
        except IndexError:
            del request.COOKIES['messages']

我也写过关于这个问题的博客(这就是上面的中间件的来源)

于 2014-04-14T15:23:14.077 回答