web-dev-qa-db-fra.com

Demande d'accès dans Django balises de modèle personnalisées

Mon code dans myapp_extras.py:

from Django import template

register = template.Library()

@register.inclusion_tag('new/userinfo.html')
def address():
    address = request.session['address']
    return {'address':address}

dans 'settings.py':

TEMPLATE_CONTEXT_PROCESSORS =(
    "Django.core.context_processors.auth",
    "Django.core.context_processors.debug",
    "Django.core.context_processors.i18n",
    "Django.core.context_processors.media",
    'Django.core.context_processors.request'
)

mais j'ai une erreur:

TemplateSyntaxError at /items/

Caught an exception while rendering: global name 'request' is not defined

Original Traceback (most recent call last):
  File "C:\Python25\lib\site-packages\Django\template\debug.py", line 71, in render_node
    result = node.render(context)
  File "C:\Python25\lib\site-packages\Django\template\__init__.py", line 915, in render
    dict = func(*args)
  File "C:\p4\projects\myproject\..\myproject\invoice\templatetags\myapp_extras.py", line 9, in address
    address = request.session['address']
NameError: global name 'request' is not defined

J'ai référencé celui-ci Dans Django, est-il possible d'accéder à la session utilisateur actuelle à partir d'une balise personnalisée? .

68
icn

request n'est pas une variable dans cette portée. Vous devrez d'abord l'obtenir du contexte. Passer takes_context au décorateur et ajoutez context aux arguments de la balise .

Comme ça:

@register.inclusion_tag('new/userinfo.html', takes_context=True)
def address(context):
    request = context['request']
    address = request.session['address']
    return {'address':address}
148

J'ai essayé la solution ci-dessus (d'Ignacio Vazquez-Abrams) et cela n'a pas fonctionné jusqu'à ce que je découvre que les processeurs de contexte ne fonctionnent qu'avec la classe wrapper RequestContext.

Donc, dans la méthode d'affichage principal, vous devez ajouter la ligne suivante:

from Django.template import RequestContext        
return render_to_response('index.html', {'form': form, }, 
                              context_instance = RequestContext(request))
11
abovesun

J'ai fait comme ça:

from Django import template
register = template.Library()

def do_test_request(parser,token):
    try:
        tag_name = token.split_contents() # Not really useful
    except ValueError:
        raise template.TemplateSyntaxError("%r error" % token.contents.split()[0])
    return RequestTestNode()

class RequestTestNode(template.Node):
    def __init__(self,):
        self.request = template.Variable('request')
    def render(self, context):
        rqst = self.request.resolve(context)
        return "The URL is: %s" % rqst.get_full_path()

register.tag('test_request', do_test_request)

Il existe également une fonction appelée resolve_variable, mais c'est obsolète.

J'espère que ça aide!

7
santiagobasulto