Django:有什么方法可以避免在每次请求时查询request.user吗?

时间:2011-05-10 23:10:25

标签: django django-authentication django-sessions

对于我的网站,几乎每个页面都有一个标题栏显示“欢迎,ABC”,其中“ABC”是用户名。这意味着将为每个请求调用request.user,导致数据库一次又一次地命中。

但是一旦用户登录,我应该能够将他的user实例存储在他的cookie中并加密它。这样我就可以避免重复访问数据库而只是从cookie中检索request.user

你会如何修改Django来做到这一点?是否有任何Django插件可以满足我的需求?

由于

4 个答案:

答案 0 :(得分:4)

您想要使用会话中间件,并且您想要阅读documentation。会话中间件支持多个session engines。理想情况下,您使用memcached或redis,但you could write your own session engine to store all the data in the user's cookie。启用中间件后,它将作为请求对象的一部分提供。您与request.session进行交互,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!') 就像一个字典,使其易于使用。以下是文档中的几个示例:

这个简单化的视图在用户发布评论后将has_commented变量设置为True。它不允许用户多次发表评论:

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.")

这种简单的视图记录了网站的“成员”:

{{1}}

答案 1 :(得分:4)

这种过度优化的气味。从db获取用户是每次请求的单击,如果您也使用Profile模型,则可能是两次。如果您的网站是额外的两个查询对性能产生重大影响,那么您可能会遇到更大的问题。

答案 2 :(得分:2)

使用django(django.contrib.auth.middleware)提供的身份验证中间件将用户附加到请求对象。它为django.contrib.auth。 init 中的get_user函数提供了一个函数,以便从您正在使用的后端获取用户。您可以轻松更改此功能以在其他位置(例如cookie)查找用户。

当用户登录时,django将userid放入会话中(request.session [SESSION_KEY] = user.id)。当用户注销时,它会从会话中删除用户的ID。您可以覆盖这些登录和注销功能,以便将用户对象存储在浏览器中cookie的浏览器cookie / erase用户对象中。这两个函数也在django.contrib.auth中。 init

请参阅此处了解Cookie:Django Cookies, how can I set them?

答案 3 :(得分:1)

一旦你有适当的缓存,数据库命中的数量应该显着减少 - 然后我再也不是真正的缓存专家。我认为修改request.user以解决您的问题是个坏主意。我认为更好的解决方案是创建一些实用程序,方法或自定义模板标记,尝试从cookie加载您的require用户数据,并返回结果。如果在cookie中找不到用户数据,则应调用request.user,将数据保存到cookie,然后返回结果。您可以使用post_save信号来检查用户数据的更改,以便您可以根据需要更新cookie。