12

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

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

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

谢谢

4

4 回答 4

8

这有过度优化的味道。从数据库中获取用户是每个请求的一次点击,如果您也使用 Profile 模型,则可能是两次。如果您的网站使得额外的两个查询对性能产生很大影响,那么您可能会遇到更大的问题。

于 2011-05-11T07:16:01.887 回答
5

您想使用会话中间件,并且需要阅读文档。会话中间件支持多个会话引擎。理想情况下,您会使用 memcached 或 redis,但您可以编写自己的会话引擎来将所有数据存储在用户的 cookie中。启用中间件后,它就可以作为请求对象的一部分使用。您与 进行交互request.session,它的作用就像一个字典,使其易于使用。以下是文档中的几个示例:

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

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!')

这个简单的视图记录了站点的“成员”:

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.")
于 2011-05-11T01:38:16.903 回答
2

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

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

请参阅此处设置 cookie:Django Cookies,我如何设置它们?

于 2011-05-11T02:12:33.047 回答
1

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

于 2011-05-11T00:05:10.717 回答