/ en / Object类型为' __ proxy __'不是JSON可序列化的

时间:2018-01-26 01:03:44

标签: json django python-3.x

我试图在我的django项目中实现面包屑。为了实现这一点,我创造了一个mixin,它由我拥有的每一个视图继承。这是代码:

class BreadcrumbMixin(object):
    index = False
    url_name = None
    verbose_name = None

    def breadcrumbUpdate(self, breadcrumb, new_value):
        for i in range(len(breadcrumb)):
            if breadcrumb[i]['url_name'] == new_value['url_name']:
                breadcrumb = breadcrumb[:i + 1]
        breadcrumb.append(new_value)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        new_value = {
            'url_name' : self.url_name,
            'verbose_name' : self.verbose_name,
            'url' : reverse_lazy(self.url_name, **kwargs)
        }

        if self.index:
            self.request.session['breadcrumb'] = [new_value,]
        else:
            self.breadcrumbUpdate(self.request.session['breadcrumb'], new_value)
        return context

属性indexurl_nameverbose_name在每个继承它的视图中设置。例如:

class Index(BreadcrumbMixin, TemplateView):
    template_name = 'crud/index.html'
    index = True
    url_name = 'index' # Name argument used in urls.py
    verbose_name = _('Index')

它基本上使用这些信息来制作一个dicts列表,使用session字典传递给模板。在模板中,它被调用如下:

<div style="margin-left: 10px;">
    {% for element in request.session.breadcrumb %}
        <a href="{{ element.url }}" class="breadcrumb"> {{ element.verbose_name }} </a>
    {% endfor %}
</div>

问题是,它给了我标题中提到的错误。这是追溯:

Environment:


Request Method: GET
Request URL: http://localhost:8000/en/

Django Version: 2.0
Python Version: 3.6.3
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'crud']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/home/jcarvalho/.envs/webdesk/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  35.             response = get_response(request)

File "/home/jcarvalho/.envs/webdesk/lib/python3.6/site-packages/django/utils/deprecation.py" in __call__
  97.             response = self.process_response(request, response)

File "/home/jcarvalho/.envs/webdesk/lib/python3.6/site-packages/django/contrib/sessions/middleware.py" in process_response
  58.                             request.session.save()

File "/home/jcarvalho/.envs/webdesk/lib/python3.6/site-packages/django/contrib/sessions/backends/signed_cookies.py" in save
  41.         self._session_key = self._get_session_key()

File "/home/jcarvalho/.envs/webdesk/lib/python3.6/site-packages/django/contrib/sessions/backends/signed_cookies.py" in _get_session_key
  77.             serializer=self.serializer,

File "/home/jcarvalho/.envs/webdesk/lib/python3.6/site-packages/django/core/signing.py" in dumps
  109.     data = serializer().dumps(obj)

File "/home/jcarvalho/.envs/webdesk/lib/python3.6/site-packages/django/core/signing.py" in dumps
  87.         return json.dumps(obj, separators=(',', ':')).encode('latin-1')

File "/usr/lib64/python3.6/json/__init__.py" in dumps
  238.         **kw).encode(obj)

File "/usr/lib64/python3.6/json/encoder.py" in encode
  199.         chunks = self.iterencode(o, _one_shot=True)

File "/usr/lib64/python3.6/json/encoder.py" in iterencode
  257.         return _iterencode(o, 0)

File "/usr/lib64/python3.6/json/encoder.py" in default
  180.                         o.__class__.__name__)

Exception Type: TypeError at /en/
Exception Value: Object of type '__proxy__' is not JSON serializable

根据我的理解,它无法序列化模板中使用的痕迹,但为什么?

PS:我从未直接使用过JSON,所以我不知道如何处理它。

1 个答案:

答案 0 :(得分:1)

使用JSONSerializer在会话对象中存储数据时,该数据必须只包含可以转换为json的值。

在你的代码中,你使用的是一些懒惰的对象,这就是你得到__proxy__的地方。这些必须在序列化之前转换为字符串。

new_value = {
        'url_name' : self.url_name,
        'verbose_name' : str(self.verbose_name),
        'url' : str(reverse_lazy(self.url_name, **kwargs))  # or just reverse()
    }

您也可以write your own serializer或使用DjangoJSONEncoder(我自己没有尝试过,但是阅读文档时,似乎序列化程序可以处理惰性对象。)