Django 在自定义标签中判断用户是否已认证

0 投票
4 回答
2288 浏览
提问于 2025-04-16 09:17

我正在尝试创建一个自定义标签。在这个自定义标签里,我想加入一些逻辑,用来检查用户是否已登录,然后根据这个状态来渲染标签。现在我有了这个:

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)

当我运行这个的时候,出现了这个错误:

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

渲染这个标签的视图最后是这样的:

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

为什么这个标签没有得到一个RequestContext对象,而是得到了一个Context对象?我该如何让这个标签接收到RequestContext,而不是Context呢?

补充:

不管是否可以在自定义标签里获取RequestContext,我还是想知道在自定义标签中判断用户的登录状态的“正确”或最佳方法是什么。如果这不可能的话,那这种逻辑是不是应该放在别的地方?那应该放在哪里呢?

4 个回答

1

我不太明白你的视图是怎么和模板标签关联起来的。因为我知道是Django的模板系统来渲染这个标签,所以上下文其实是一个字典。你可以试试这个,希望能帮到你。

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

默认情况下,渲染模板时会使用一个叫做 django.template.Context 的实例,但你可以在视图中覆盖这个设置。你可以通过将 django.template.Context 的子类作为 context_instance 参数传递给 render_to_response,或者直接创建这个子类的实例,并将其传递给 Template.render

为了方便,Django 提供了一个有用的预定义子类:django.template.RequestContextRequestContext 会在你的设置文件中查找一个叫做 TEMPLATE_CONTEXT_PROCESSORS 的设置,这个设置应该是一个可调用对象的元组,每个对象都应该返回一个字典;RequestContext 会遍历这些可调用对象,调用它们,并将返回字典中的键值对添加到模板上下文中作为变量。想了解更多,可以查看 这些 链接

要将当前用户添加到你的模板上下文中,你需要使用 django.core.context_processors.auth

  1. settings.py 中,将 django.core.context_processors.auth 添加到你的上下文处理器列表中:

    TEMPLATE_CONTEXT_PROCESSORS = (
        'django.core.context_processors.auth',
        ... # Other context processors follow
    )
    
  2. 确保渲染模板的视图使用 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. 使用 RequestContext 会调用在 settings.TEMPLATE_CONTEXT_PROCESSORS 中定义的所有上下文处理器,包括 auth 上下文处理器,它会将一个名为 'user' 的上下文变量添加到你的模板上下文中。
    在你的模板标签中,你可以通过 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
    
1

最后我只是把“用户”这个参数传给标签,然后用它来判断用户是否已经认证。

撰写回答