如何用Django实现动态侧边栏?
我打算创建一个侧边栏,里面的内容会根据当前的网页地址和用户的登录状态而变化。
比如说:默认的侧边栏会显示一个登录框和一个标签云。
- 如果用户已经登录,我想显示一个用户菜单。
- 如果当前的网页地址是
/tagcloud
,我想把它从侧边栏隐藏起来。
实际上,我需要一种方法,可以在视图中做到这些:
def some_view(request):
if request.user.is_authenticated():
sidebar.remove('login')
sidebar.add('user_menu')
def tag_cloud(request):
sidebar.remove('tag_cloud')
然后,我想把 sidebar
(不通过 render_to_response
传递)传递给模板,在模板中我想做类似这样的事情:
<div id="sidebar">
{{ sidebar }}
</div>
这样做可以吗?
3 个回答
0
来自@Dominique的回答是正确的,但当你在context_processors
中写东西时,它会在网站的每个页面上加载。这可能会导致性能问题。
我认为处理动态侧边栏的正确方法是使用simpletag
,并在需要的地方使用它。
def get_sidebar():
tags = Tags.objects.filter(active=True)
latest_posts = Post.objects.all().order_by('-create_at')[:10]
html = render_to_string("sidebar.html", {
"tags": tags,
"latest_posts": latest_posts
})
return html
现在只需在模板文件中使用:
<div class="col-md-4 sidebar">
{% get_sidebar %}
</div>
另外,你可以将request
传递给simpletag
,以便使用user.is_authenticated
来检查用户是否已登录。
0
是的,你可以使用模板的继承和组合。然后把你的侧边栏放在一个父模板里,这个父模板会被你所有的模板使用或继承。这样,找到侧边栏的模板就很简单了:它在一个单独的文件里。
5
你最好把这个放在一个叫做 context_processors.py 的文件里。
这也意味着你在返回视图的时候必须使用 RequestContext。
def include_tagcloud(request):
if request.path == '/tagcould/':
tagcloud = Tags.objects.filter(active=True) #whatever
return {'tagcloud': tagcloud}
def include_login(request):
if request.user.is_authenticated():
loginform = MyLoginForm(request.POST)
#passing a Django form + POST data in the case of re-submit
return {'loginform' : loginform}
然后在你的模板里:
{% if loginform %}
<form action="accounts/login/">
{{form.as_p}}
<input type="submit" name="Login">
</form>
{% endif %}
{% if tagcloud %}
{%for tag in tagcloud %}.....{%for}
{% endif %}
在这个例子中,登录表单指向一个固定的视图,
如果你想在每个视图中都处理登录表单的提交,我就不知道该怎么做了。
编辑:如果你不使用 Django 的 CSRF 功能,你可以简单地把登录表单放在基础模板里,而不需要使用任何 Django 表单,直接指向一个登录视图:
{% if user.is_authenticated %}
<form action="accounts/login/">
<input type="text" name="username"><input type="password" name="password">
<input type="submit" name="Login">
</form>
{% endif %}