Django 在自定义标签中判断用户是否已认证
我正在尝试创建一个自定义标签。在这个自定义标签里,我想加入一些逻辑,用来检查用户是否已登录,然后根据这个状态来渲染标签。现在我有了这个:
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 个回答
我不太明白你的视图是怎么和模板标签关联起来的。因为我知道是Django的模板系统来渲染这个标签,所以上下文其实是一个字典。你可以试试这个,希望能帮到你。
user = context['user']
if user.is_authenticated():
do stuff
默认情况下,渲染模板时会使用一个叫做 django.template.Context
的实例,但你可以在视图中覆盖这个设置。你可以通过将 django.template.Context
的子类作为 context_instance
参数传递给 render_to_response
,或者直接创建这个子类的实例,并将其传递给 Template.render
。
为了方便,Django 提供了一个有用的预定义子类:django.template.RequestContext
。RequestContext
会在你的设置文件中查找一个叫做 TEMPLATE_CONTEXT_PROCESSORS
的设置,这个设置应该是一个可调用对象的元组,每个对象都应该返回一个字典;RequestContext
会遍历这些可调用对象,调用它们,并将返回字典中的键值对添加到模板上下文中作为变量。想了解更多,可以查看 这些 链接。
要将当前用户添加到你的模板上下文中,你需要使用 django.core.context_processors.auth
:
在
settings.py
中,将django.core.context_processors.auth
添加到你的上下文处理器列表中:TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.auth', ... # Other context processors follow )
确保渲染模板的视图使用
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))
使用
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
最后我只是把“用户”这个参数传给标签,然后用它来判断用户是否已经认证。