Django中的用户身份验证
几个月前我学会了如何在Django中进行用户认证,但最近我升级了版本,遇到了一些问题。今天早上我突然想到,可能一开始我就没有正确地做这件事,所以决定问问。
在我项目的urls.py文件中,我设置了两个路径:^accounts/login/$ 和 ^accounts/logout/$,这两个路径分别连接到Django自带的登录和登出视图(在django.contrib.auth.views里)。还有一个路径^accounts/profile/$,它连接到我自己写的一个视图,叫做“start_here”,这个视图的内容基本上是这样的:
def start_here(request):
if request.user:
user_obj = request.user
else:
user_obj = None
is_auth = False
if request.user.is_authenticated():
is_auth = True
return render_to_response("profile.html", {'auth': is_auth,'user': user_obj,})
现在,“profile.html”是从一个主模板master.html扩展出来的,主模板里有一个“navbar”块,这个块的内容应该在用户登录后发生变化,也就是说如果用户已经认证('auth' == True),内容应该不同(下面的代码片段展示了这部分)
{% block navbar %}
{% if auth %}
<a href="">Link A</a>
<a href="">Link B</a>
<a href="">Link C</a>
<a href="">Link D</a>
<a href="">Link E</a>
<a href="">Link F</a>
<a href="/accounts/logout/">Logout</a>
{% else %}
<a href="/accounts/login/">Login</a>
{% endif %}
{% endblock %}
我的问题是,当我登录后,重定向到/accounts/profile时,导航栏并没有显示链接A-F和登出选项,而是只显示了“登录”。它的表现和我预期的不一样,除非我手动把上面的代码块复制粘贴到profile.html里。调用render_to_response()时,我提供的上下文会传递给父模板和子模板吗?
master和profile.html的完整代码在这里:http://dpaste.com/hold/128784/,我在代码里没有看到什么可疑的地方。
3 个回答
是的,你在render_to_response()中传入的上下文会被传递给指定的模板,以及它包含或继承的所有模板。
你应该了解一下如何使用 RequestContext
还有一点需要检查...
只是确认一下:
你的个人资料模板应该以以下内容开头:
{% extends 'master.html' %}
为了确保Django能够正确识别用户,你需要在设置模块中正确启用相关功能。具体来说,你需要确保在你的settings.MIDDLEWARE_CLASSES
中启用了SessionMiddleware
和AuthenticationMiddleware
这两个模块。同时,确保auth
在你的已安装应用中,并且在启用之后运行过syncdb
。
如果你没有按照以上步骤操作,那么Django就无法检测用户是否登录,也无法正确设置请求。
这个回答虽然有点偏题,但Jim提到的使用RequestContext的建议实在太好了,我想详细解释一下怎么做。
你可以把你的 start_here
函数简化成
from django.template import RequestContext
def start_here(request):
return render_to_response("profile.html", {},
context_instance=RequestContext(request))
通过使用RequestContext,user
会自动被加入到上下文中。这样你就不需要再使用
{% if auth %}
而是直接用
{% if user.is_authenticated %}