70 votes

Demande d'accès dans les balises du modèle personnalisé de django

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 obtenu 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 fait référence à celle-ci Dans Django, est-il possible d'accéder à la session de l'utilisateur actuel à partir d'une balise personnalisée ? .

155voto

Ignacio Vazquez-Abrams Points 312628

request n'est pas une variable dans ce champ d'application. Vous devrez d'abord l'obtenir à partir du contexte. Passez takes_context au décorateur et ajoutez context aux arguments de la balise .

Comme ceci :

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

11voto

abovesun Points 1135

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

Ainsi, dans la méthode de la vue principale, vous devez ajouter la ligne suivante :

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

7voto

santiagobasulto Points 5081

J'ai procédé de cette manière :

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 elle est obsolète.

J'espère que cela vous aidera !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X