Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: any way to avoid querying for request.user on every request?

For my website pretty much every page has a header bar displaying "Welcome, ABC" where "ABC" is the username. That means request.user will be called for every single request resulting in database hits over and over again.

But once a user is logged in, I should be able to store his user instance in his cookie and encrypt it. That way I can avoid hitting the database repeatedly and just retrieve request.user from the cookie instead.

How would you modify Django to do this? Is there any Django plugins that does what I need?

Thanks

like image 731
Continuation Avatar asked May 10 '11 23:05

Continuation


2 Answers

You want to use the session middleware, and you'll want to read the documentation. The session middleware supports multiple session engines. Ideally you'd use memcached or redis, but you could write your own session engine to store all the data in the user's cookie. Once you enable the middleware, it's available as part of the request object. You interact with request.session, which acts like a dict, making it easy to use. Here are a couple of examples from the docs:

This simplistic view sets a has_commented variable to True after a user posts a comment. It doesn’t let a user post a comment more than once:

def post_comment(request, new_comment):
    if request.session.get('has_commented', False):
        return HttpResponse("You've already commented.")
    c = comments.Comment(comment=new_comment)
    c.save()
    request.session['has_commented'] = True
    return HttpResponse('Thanks for your comment!')

This simplistic view logs in a "member" of the site:

def login(request):
    m = Member.objects.get(username=request.POST['username'])
    if m.password == request.POST['password']:
        request.session['member_id'] = m.id
        return HttpResponse("You're logged in.")
    else:
        return HttpResponse("Your username and password didn't match.")
like image 115
zeekay Avatar answered Oct 18 '22 04:10

zeekay


The user is attached to the request object using the Authentication Middleware provided by django (django.contrib.auth.middleware). It users a function the get_user function in django.contrib.auth.init to get the user from the backend you are using. You can easily change this function to look for the user in another location (e.g. cookie).

When a user is logged in, django puts the userid in the session (request.session[SESSION_KEY]=user.id). When a user logs off, it erases the user's id from the session. You can override these login and logoff functions to also store a user object in the browsers cookie / erase user object from cookie in the browser. Both of these functions are also in django.contrib.auth.init

See here for settting cookies: Django Cookies, how can I set them?

like image 40
systemizer Avatar answered Oct 18 '22 04:10

systemizer