开发者

Django Find Out if User is Authenticated in Custom Tag

开发者 https://www.devze.com 2023-02-02 05:14 出处:网络
I\'m trying to create a custom tag. Inside this custom tag, I want to be able to have some logic that checks if the user is logged in, and then have the tag rendered accordingly. This is what I have:

I'm trying to create a custom tag. Inside this custom tag, I want to be able to have some logic that checks if the user is logged in, and then have the tag rendered accordingly. This is what I have:

def user_actions(context):
    request = template.Variable('request').resolve(context)
    return { 'auth': request['user'].is_athenticated() }

register.inclusion_tag('layout_elements/user_actions.html', takes_context=True)(user_actions)

When I run this, I get this error:

Caught VariableDoesNotExist while rendering: Failed lookup for key [request] in u'[{}]'

The view that renders this ends like this:

return render_to_response('start/home.html', {}, context_instance=RequestContext(request))

Why doesn't the tag get a RequestContext object instead of the Context object? How can I get the tag to receive the RequestContext instead of the Context?

EDIT:

Whether or not it's possible to get a RequestContext inside a custom tag, I'd still be interested to know the "correct" or best way to determine a user's authenticati开发者_开发问答on state from within the custom tag. If that's not possible, then perhaps that kind of logic belongs elsewhere? Where?


By default, an instance of django.template.Context is used in rendering templates, but you can override this in your view, either by passing a subclass of django.template.Context as the context_instance keyword argument to render_to_response, or by instantiating the subclass, and passing it directly to Template.render.

For convenience, Django provides a useful, pre-defined Context subclass: django.template.RequestContext. RequestContext looks in your settings file for a setting called TEMPLATE_CONTEXT_PROCESSORS, which should be a tuple of callable objects, each of which should return a dictionary; RequestContext will loop over each callable, call it, and add the key/value pairs from its returned dictionary to the template context as variables. Check out these links for a more detailed explanation.

To add the current user to your template context, you need django.core.context_processors.auth:

  1. Add the django.core.context_processors.auth context processor to your list of context processors in settings.py:

    TEMPLATE_CONTEXT_PROCESSORS = (
        'django.core.context_processors.auth',
        ... # Other context processors follow
    )
    
  2. Ensure the view than renders the template which calls your custom tag uses RequestContext:

    from django.template.context import RequestContext
    from django.shortcuts import render_to_response
    def my_view(request):
        # Do some stuff
        return render_to_response('templates/view.html', 
            context_instance=RequestContext(request))
    
  3. Using RequestContext calls all context processors defined in settings.TEMPLATE_CONTEXT_PROCESSORS, including the auth context processor, which adds a context variable 'user' to your template context.
    In your template tag, you can access this variable via context['user']

    @register.inclusion_tag('templates/custom/tag.html', takes_context=True)
    def custom_tag(context):
        user = context['user']
        if user.is_authenticated():
            # Some stuff for the logged-in users
        else:
            # Stuff for anonymous users
    


i dont see how your view is linked to the template tag, because from what i know its django's template system that renders the tag, so the context is a dictionary, try this, hopefully it helps

user = context['user']
if  user.is_authenticated():
     do stuff


The "context" of a template node is a different thing to the RequestContext. A Context is also a dictionary, so if it has a user at all it would be accessed via context['user'].

The template nodes context contains information to help it render itself within the template, after doing some reading of the docs, I cannot find any way to access the RequestContext which would be associated with the request via the django.template.Context.


Moreover django.template.RequestContext extends from django.template.Context specifically in order to handle the added request object which would contain the user. So it is no surprise that Context would not have access to it.

See the source code of Context for proof.

How to get the user

After a bit of searching I found the django.template.resolve_variable method which can be used as follows:

from django.template import resolve_variable

user = resolve_variable('user', context)

Where context is a template context.


I ended up just passing the "user" parameter to the tag and using that to decide if the user was auth'd or not.

0

精彩评论

暂无评论...
验证码 换一张
取 消