views:

646

answers:

3

I have some code that gets the current logged in user.

userID = request.session.get("_auth_user_id")
    if userID:
     loggedin_user = User.objects.get(pk=int(userID))
    else:
     loggedin_user = None

I want the username to show up on every page.

At the moment I am putting the code in every view and passing the user object to every template

return render_to_response('index.html', {loggedin_user})

This seems to go against django's D.R.Y ethic. How can I do this with repeating myself?

EDIT: Maybe User was a bad example.

What if I wanted to get a list of objects from the database,

items = Item.objects.all()

and list them on everypage.

Do I have to write that code and pass the list to the template in every view. Or can I write some code once that will make that list available to all templates?

+3  A: 

The user ID already exists within the session. As such, you do not need to keep passing it around.

{{ request.session._auth_user_id }}

That should work, but you need to add this in your TEMPLATE_CONTEXT_PROCESSORS in your settings file:

django.core.context_processors.request

In your render_to_response, you'd need to add the request as a parameter. For example:

 return render_to_response('test.html',{}, context_instance=RequestContext(request))
AlbertoPL
Sorry , I made a typoI want to pass the whole User object to the template not just the id
Cato Johnston
Again, the whole user is already there if you've added the user to the session, so you should be able to access any of its fields.
AlbertoPL
@Cato: {{ user }} is available for any template if you put django.core.context_processors.auth into your settings.TEMPLATE_CONTEXT_PROCESSORS, but anonymous users are not None, they are instances of AnonymousUser. See http://docs.djangoproject.com/en/dev/topics/auth/#authentication-data-in-templates
Van Gale
+1  A: 

What about request.user?

if request.user.is_authenticated():
    name = request.user.username
else:
    name = "Anonymous"

Anyway, if it wasn't already available in django, I'd suggest you to write a Middleware class just like django.contrib.sessions.middleware.SessionMiddleware or django.contrib.auth.middleware.AuthenticationMiddleware. That class alters the request details before they are sent to a view.

If you needed it on a per-view basis, you could write a decorator to do that small bit, and @decorator the views you want.

Alcides
+1  A: 

You should use a custom template tag for something like that. You can fetch the data you need in the custom tag, and send it to the template. All you need to remember is to load the tag up in the template file you're going to use it in.

Alex Jillard
but then you have the {% load my _template_tag %} in 20 templates ... this isn't DRY
Andre Bossard
If you're using it that often, chances are it's in a parent template that you're extending, and therefore, you'll only have it in one spot. If that isn't the case, you could probably use a custom context processor.
Alex Jillard