views:

272

answers:

3

I learned how to authenticate users in Django months ago, but I've since upgraded and am having some problems so it occurred to me this morning that I may not have been doing it correctly from the start so I decided to ask.

In my project's urls.py file I've got ^accounts/login/$ and ^accounts/logout/$ both wired up to the built-in login() and logout() views (at django.contrib.auth.views) and ^accounts/profile/$ is connected to a view I've written, called "start_here" whose contents are basically this:

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,})

Now, "profile.html" extends a master template, called master.html, inside which is a "navbar" block whose contents are supposed to change if 'auth' == True (snippet below)

{% 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 %}

My problem is that when I log in, and it redirects to /accounts/profile, the navbar doesn't display Links A-F + Logout, it displays only "login". It doesn't work the way I expect it to unless I manually copy-paste the above block into profile.html. When calling render_to_response(), does the context I provide get passed to the parent template as well as the child?

Full source to master and profile.html: http://dpaste.com/hold/128784/ I don't see anything suspect in the code.

+1  A: 

Yes the context you pass in render_to_response() is passed to the named templates and ALL the templates it includes or inherits from.

You should look into Using RequestContext

Another thing to check...

Just making sure:

your profile template begins with

{% extends 'master.html' %}
Jiaaro
Yup, that's how it begins.
cornjuliox
+1  A: 

In order to make sure django correctly identifies users, you need to make sure it is properly enabled in your settings module. specifically, you need to make sure that the SessionMiddleware and AuthenticationMiddleware modules are enabled in your settings.MIDDLEWARE_CLASSES. also be sure that auth is in your installed apps and you have run syncdb since enabling it.

If you have not taken the above steps, then django will not be able to detect when users have logged in and perform request setup properly.

TokenMacGuy
+6  A: 

This answer is tangential, but Jim's suggestion to use RequestContext is so good I want to explicitly explain how to do it.

You can reduce your start_here function to

from django.template import RequestContext

def start_here(request):
    return render_to_response("profile.html", {},
        context_instance=RequestContext(request))

By using RequestContext, user is automatically added to the context. Instead of using

{% if auth %}

use

{% if user.is_authenticated %}
Alasdair
I agree with this approach
Jiaaro