始终将用户包含在 django 模板上下文中

Posted

技术标签:

【中文标题】始终将用户包含在 django 模板上下文中【英文标题】:Always including the user in the django template context 【发布时间】:2010-09-07 16:18:18 【问题描述】:

我正在为一家小公司开发一个小型 Intranet 网站,用户应该可以在该网站上发帖。我设想了一个非常简单的身份验证机制,人们只需输入他们的电子邮件地址,并收到一个唯一的登录 url,它会设置一个 cookie,该 cookie 将始终在未来的请求中识别他们。

在我的模板设置中,我有 base.html,其他页面对此进行了扩展。我想在 base.html 中显示登录或注册按钮,但如何确保必要的变量始终是上下文的一部分?似乎每个视图只是根据自己的喜好设置上下文,并且没有全局上下文人口。有没有一种方法可以在不将用户包括在每个上下文创建中的情况下做到这一点?

或者我是否必须创建自己的自定义快捷方式才能正确设置上下文?

【问题讨论】:

【参考方案1】:

如果您在TEMPLATE_CONTEXT_PROCESSORS 中已经有"django.core.context_processors.auth",则不需要为用户对象编写上下文处理器并且如果您正在使用@987654323 @在你看来。

如果您使用 django 1.4 或最新版本,该模块已移至 django.contrib.auth.context_processors.auth

【讨论】:

如果未使用 RequestContext,则此模板上下文变量不可用。 没错,你必须使用RequestContext 使用 Django 1.3 中的 render() (docs.djangoproject.com/en/dev/topics/http/shortcuts/#render) 始终自动包含 RequestContext。 第一个链接应该是:docs.djangoproject.com/en/dev/topics/auth/default/…【参考方案2】:

@Ryan:关于预处理器的文档有点小

@Staale:每次调用视图中的模板时,将用户添加到上下文中,DRY

解决方案是使用预处理器

A:在您的设置中添加

TEMPLATE_CONTEXT_PROCESSORS = (
    'myapp.processor_file_name.user',
)

B:在 myapp/processor_file_name.py 中插入

def user(request):
    if hasattr(request, 'user'):
        return 'user':request.user 
    return 

从现在开始,您可以在模板中使用用户对象功能。

 user.get_full_name 

【讨论】:

Django 给出错误Put 'django.contrib.auth.context_processors.auth' in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application. 即使我这样做了,模板仍然不知道user @hobbes3 因为你没有使用 RequestContext 上下文处理器不会被执行。 @rebus 实际上在我的views.py 中,我传递了一个使用render_to_resposneRequestContext 相反的简单字典。感谢您的帮助。【参考方案3】:

从更一般的意义上说,不必在每个视图中显式设置变量,听起来你想看看编写自己的 context processor。

来自文档:

上下文处理器有一个非常简单的接口:它只是一个 Python 函数,它接受一个参数,一个 HttpRequest 对象,并返回一个添加到模板上下文的字典。每个上下文处理器都必须返回一个字典。

【讨论】:

【参考方案4】:

提示在每个答案中,但再次从“零开始”,对于新手:

默认情况下,身份验证数据(几乎)在模板中——有一个小技巧:

views.py:

from django.template import RequestContext
...
def index(request):
    return render_to_response('index.html', 
                              'var': 'value',
                              context_instance=RequestContext(request))

index.html:

...
Hi,  user.username 
var:  value 
... 

从这里:https://docs.djangoproject.com/en/1.4/topics/auth/#authentication-data-in-templates

如果 RequestContext 是,则此模板上下文变量不可用 没有被使用。

【讨论】:

【参考方案5】:

@戴夫 要在我的模板中使用 user.username,我将不得不使用 requestcontext 而不仅仅是一个普通的 map/hash:http://www.djangoproject.com/documentation/templates_python/#subclassing-context-requestcontext

所以我猜模板引擎没有检查全局变量。

但是 RequestContext 有一些预填充类,我可以研究这些类来解决我的问题。谢谢。

【讨论】:

【参考方案6】:

如果您可以将您的身份验证与Django authentication scheme 挂钩,您将能够使用request.user

我认为这应该只是根据您的 Cookie 的内容调用authenticate()login() 的情况。

编辑:@Staale - 我总是使用locals() trick 作为我的上下文,所以我的所有模板都可以看到requestrequest.user。如果你不是,那么我想这不会那么简单。

【讨论】:

【参考方案7】:

默认情况下可以,通过执行以下步骤,确保您在设置中添加了上下文“django.contrib.auth.context_processors.auth”。默认情况下它添加在settings.py中,所以它看起来像这样

TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.auth',)

你可以像这样访问用户对象,

% if user.is_authenticated %
<p>Welcome,  user.username . Thanks for logging in.</p>
% else %
    <p>Welcome, new user. Please log in.</p>
% endif %

欲了解更多信息,请参阅此处http://docs.djangoproject.com/en/1.2/topics/auth/#authentication-data-in-templates

【讨论】:

这种情况下还需要使用RequestContext而不是Context。 这已经过时了,请看下面@synkc 的回答【参考方案8】:

使用上下文处理器。 https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-TEMPLATES-OPTIONS

settings.py

'OPTIONS': 
        'context_processors': [
            'django.template.context_processors.debug',
            'django.template.context_processors.request',
            'django.contrib.auth.context_processors.auth',
            'django.contrib.messages.context_processors.messages',
            'myapp.functions.test'
        ],
,

myapp/functions.py

def test(request):
    return 'misc': 'misc'

【讨论】:

以上是关于始终将用户包含在 django 模板上下文中的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中,是不是可以从包含标记内的父模板上下文访问当前用户会话?

处理 django 包含模板标签中的请求

将对象从模板传递给 django 视图(控制器)

Django 模板 - 更改“包含”模板的上下文

Django:不能将变量传递给包含的模板?

如何将上下文变量与 Django 模板中的 SQL ID 进行比较?