我正在 Django 中编写一个自定义标记,它应该输出存储在用户会话中的值,但是我找不到从自定义标记函数中访问会话对象的方法。有没有办法做到这一点,而无需手动将会话对象分配给上下文变量?
5 回答
您应该能够在 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',)
这将与当前答案执行相同的操作,而无需添加自定义文件。
Sebastian 无意冒犯,因为这似乎是一个有用的 hack,但奇怪的是,在 12 月 24 日,在一篇关于在 Admin 中访问用户数据的博客文章中,Django 的发布经理 James Bennett谈到了使用 threadlocal黑客:
一个很大的免责声明:这些类型的功能有很多潜在的用途。他们中的许多人都是错误的和愚蠢的,你不应该尝试它们。...此外,您偶尔会看到有人建议可以通过所谓的“threadlocal hack”获得这些功能;这基本上涉及将 request.user 粘贴到一种神奇的全局可用变量中,如果您不知道自己在做什么,那么使用它是一件非常糟糕的事情。即使您确实知道自己在做什么,这通常也是一件非常糟糕的事情,因为您可能只是因为懒惰并且不想确保正确传递信息而这样做。因此,如果您看到有人建议您使用“threadlocal”执行此操作,请忽略该人。
并不是说您应该忽略 Sebastian,但可能值得追求其他途径而不是使用不被认为是最佳实践的 threadlocal。
您可以使用自定义上下文处理器来执行此操作(请参阅http://docs.djangoproject.com/en/dev/ref/templates/api/)
在这种情况下,您将在 settings.py 文件的同一级别创建一个名为 context_processors.py 的新文件,其中包含:
def add_session(request):
return {'session': request.session}
然后,在您的 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",
'context_processors.add_session',)
您现在可以在自定义标签中引用 context['session']。
请注意,这仅适用于分配了 RequestContext 呈现的模板,如以下代码所示:
def test(request):
return render_to_response('test.html',{}, context_instance=RequestContext(request))
我发现这很有用:http ://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser
您可以使用中间件获取用户信息并将其存储在本地线程中,然后将其与您的标签定义一起使用。
使用django-annoying中的 render_to 装饰器似乎是最好的选择(如另一个关于 stackoverflow的问题中所见)