我试图在我的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
属性index
,url_name
和verbose_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,所以我不知道如何处理它。
答案 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(我自己没有尝试过,但是阅读文档时,似乎序列化程序可以处理惰性对象。)