我正在使用django 1.4并尝试将this article末尾描述的代码转换为自定义标签。这意味着我需要访问请求中的is_secure和site_name值。这是settings.py中的我的CONTEXT_PROCESSORS:
CONTEXT_PROCESSORS = (
'django.core.context_processors.request',
'django.contrib.auth.context_processors.auth',
)
这是我的模板标记代码:
from django import template
register = template.Library()
@register.simple_tag(takes_context=True)
def full_static_url(context, url):
request = context['request']
scheme = 'http'
if request.is_secure:
scheme += 's'
return scheme + '://' + request.site_name + context['STATIC_URL'] + url
在我的视图代码中,我使用了新的渲染快捷方式,如下所示:
return render(request, 'myapp/mytemplate.html', {'foo':bar})
我在模板中这样称呼它:
{% full_static_url "images/logo.gif" %}
问题是,当它到达 request = context ['request'] 行时,它会抛出一个KeyError,因为'request'不在上下文中。
我在这里做错了什么?
完整追溯是:
File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "C:\Projects\blah\blah\myapp\views\myview.py" in manifestcosts
44. return render(request, 'myapp/mytemplate.html', {'foo':bar})
File "C:\Python27\lib\site-packages\django\shortcuts\__init__.py" in render
44. return HttpResponse(loader.render_to_string(*args, **kwargs),
File "C:\Python27\lib\site-packages\django\template\loader.py" in render_to_string
176. return t.render(context_instance)
File "C:\Python27\lib\site-packages\django\template\base.py" in render
140. return self._render(context)
File "C:\Python27\lib\site-packages\django\template\base.py" in _render
134. return self.nodelist.render(context)
File "C:\Python27\lib\site-packages\django\template\base.py" in render
823. bit = self.render_node(node, context)
File "C:\Python27\lib\site-packages\django\template\debug.py" in render_node
74. return node.render(context)
File "C:\Python27\lib\site-packages\django\template\defaulttags.py" in render
185. nodelist.append(node.render(context))
File "C:\Python27\lib\site-packages\django\template\base.py" in render
1107. return func(*resolved_args, **resolved_kwargs)
File "C:\Projects\blah\blah\myapp\templatetags\mytags.py" in full_static_url
25. request = context['request'] #TODO this fails with an KeyError, don't know why
File "C:\Python27\lib\site-packages\django\template\context.py" in __getitem__
54. raise KeyError(key)
Exception Type: KeyError at /myapp/myurl/110505081136179000/
Exception Value: 'request'
答案 0 :(得分:10)
解决此问题的正确方法是在settings.py文件中添加TEMPLATE_CONTEXT_PROCESSORS += ("django.core.context_processors.request",)
。
确保先使用TEMPLATE_CONTEXT_PROCESSORS
导入from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
,否则无效。
答案 1 :(得分:1)
问题很可能是你使用常规上下文渲染模板,如下所示:
return render_to_response("myapp/template.html", {"some_var": a_value})
请记住,上下文处理器仅适用于RequestContext
个实例。这意味着您必须在RequestContext
电话中明确创建render_to_response
:
return render_to_response("myapp/template.html", {"some_var": a_value},
context_instance=RequestContext(request))
甚至更好,使用新的render
快捷方式:
return render(request, "myapp/template.html", {"some_var": a_value})
答案 2 :(得分:0)
我通过改变
解决了这个问题return render(request, 'myapp/mytemplate.html', {'foo':bar})
到
return render( RequestContext(request), 'myapp/mytemplate.html', {'foo':bar})
我希望这有助于其他人,我浪费了大约8个小时:p
答案 3 :(得分:0)
我在render()中的template.Node对象中发生了这种情况。事实证明,有时上下文中有“请求”,有时则不然。
像其他人建议的那样,RequestContext(request)
是关键。我的猜测是,有时会在没有像这样初始化请求的情况下调用上下文。
我改变了我的功能
def render(self, context):
request = context['request'] # Failing here
到
def render(self, context):
request = RequestContext(context)['request']['request']
这一切都是正确的。
如果上下文对象未正确初始化,这将强制执行请求对象。出于某种原因,我不得不两次添加['request'],但似乎工作正常
编辑:我说得太早,似乎空白的背景无法修复。相反,你可以尝试一种解决方法:
request = context.get('request')
if request is None:
return ''
我的页面似乎仍然正常,所以我不确定这些不良背景的来源。