2012-04-23 2 views
3

Я использую django 1.4 и пытаюсь преобразовать код, описанный в конце this article, в customtag. Это означает, что мне нужен доступ к значениям is_secure и site_name из запроса. Вот мои CONTEXT_PROCESSORS в settings.py:django custom templatetag не получает запрос в контексте

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, потому что «запрос» не находится в контексте.

Что я здесь делаю неправильно?

Полный отслеживающий является:

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

Попробуйте это. http://squeeville.com/2009/01/27/django-templatetag-requestcontext-and-inclusion_tag/ – CppLearner

+0

@CppLearner Я попробовал, но, как я подозревал, та же проблема. KeyError, когда он пытается получить запрос из контекстной карты. – ThatAintWorking

+0

Как и в случае проверки работоспособности, у вас есть действительно CONTEXT_PROCESSORS или лучший вариант TEMPLATE_CONTEXT_PROCESSORS в ваших настройках.py? – loomi

ответ

10

Правильный способ устранить эту проблему - добавить TEMPLATE_CONTEXT_PROCESSORS += ("django.core.context_processors.request",) в файл settings.py.

Обязательно импортируйте TEMPLATE_CONTEXT_PROCESSORS с from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS, иначе это не сработает.

+0

Это то, что я закончил после комментария estecb на ответ Pheonix выше. Вы первым написали это как ответ. Благодаря! – ThatAintWorking

+1

В более поздних версиях Django TEMPLATE_CONTEXT_PROCESSORS устарел и был заменен на TEMPLATES ['OPTIONS'] ['context_processors']. Вы, что импортировать вместо этого в этом обстоятельстве? – Teekin

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}) 
+0

На самом деле, я использую ярлык рендеринга. Я должен был упомянуть об этом в своем описании. Я добавлю его сейчас. – ThatAintWorking

+0

На всякий случай, я попробовал метод render_to_response (с RequestContext) той же самой проблемы. – ThatAintWorking

+0

Ну, в этом случае код выглядит правильно, вы можете вставить точную трассировку, которую вы получаете? – koniiiik

0

Я решил, изменив

return render(request, 'myapp/mytemplate.html', {'foo':bar}) 

до

return render(RequestContext(request), 'myapp/mytemplate.html', {'foo':bar}) 

Я надеюсь, что это помогает кому-то другому, я потратил около 8 часов: p

+5

второй код неправильный, рендер уже делает это. Вероятно, вам не хватает 'django.core.context_processors.request' в' TEMPLATE_CONTEXT_PROCESSORS'. – nitely

+1

^^ Это правильный ответ - спасибо! – donturner

+0

Это работает, но IMHO это не лучшее решение. Я думаю, что решение лития по добавлению к TEMPLATE_CONTEXT_PROCESSORS является лучшим решением. – ThatAintWorking

0

У меня это произошло в шаблоне.Node-объект в render(). Оказалось, что иногда контекст имел в нем «запрос», в других случаях это не так.

Как и любой другой, RequestContext(request) является ключевым. Я предполагаю, что иногда контекст вызывается без инициализации запроса.

я изменил свою функцию от

def render(self, context): 
     request = context['request'] # Failing here 

в

def render(self, context): 
     request = RequestContext(context)['request']['request'] 

и все уладилось.

Это заставит объект запроса в случае, если объект контекста не был инициализирован должным образом. По какой-то причине я должен добавить [ «запрос»] дважды, но это, кажется, работает прекрасный


EDIT: Я говорил слишком рано, кажется пустой контекст не может быть исправлена. Вместо этого вы могли бы попробовать обходной путь:

request = context.get('request') 
if request is None: 
    return '' 

Моя страница все еще, кажется, работает хорошо, так что я не совсем уверен, где эти плохие контексты откуда.

Смежные вопросы