开始使用Django中间件,会话和缓存

时间:2013-12-20 10:10:13

标签: django django-middleware django-sessions django-cache

我的Django应用程序中的每个用户都与一个部门相关联,几乎每个请求都涉及一些与部门相关的处理。所以我喜欢在整个应用程序中使部门对象可用。

其中哪一项(如果有的话)是最合适的方法:

  1. 自定义中间件只是从数据库中检索相关部门并将其附加到request对象,比如request.department,有点像Django' AuthenticationMiddleware使当前登录用户request.user可用。 (例如,参见herehere
  2. 当用户登录时将部门放置在会话中,然后使用Django的request.session界面在视图中检索它。
  3. 我还没有机会熟悉Django的缓存功能,但我想最终在每个用户的基础上缓存部门以避免额外的数据库命中每一个要求。我看到了Django's sessions provide built-in caching support。我还想象缓存也可以用第一种方法实现。

    对于这类事情,使用会话(上面的#2)而不是自定义中间件(上面的#1)是否有优势?从内部API角度来看,中间件方法看起来更简洁,但我猜测这正是会话设计的目的 - 所以这可能是开始使用它们的合适机会?

    感谢任何指导!

1 个答案:

答案 0 :(得分:1)

基本上两种方法都非常相似。 request.session方法可以通过手动设置中间件缓存来消除额外的步骤。会话方法的坏处是,如果您使用缓存存储,则无法保证数据可用。例如,可能有0.1%的用户使用了禁用的cookie,您正在使用内存缓存存储,因此在重新部署时可能需要重新启动内存缓存服务器,并且您的登录用户将丢失其数据等。总之,我不会使用带缓存存储的会话来获取关键数据。在我的项目中,我更喜欢使用第一选项,因为它让我有更高的控制水平。

您可以设置为请求添加view_name变量的特殊中间件,并允许控制显示的位置和内容:

class NameMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        # add current view
        if isinstance(view_func, str):
            request.view_name = view_func
        elif hasattr(view_func, '__name__'):
            request.view_name = view_func.__name__

然后,您将更好地控制在何处为请求提供附加信息,例如在context_processors中,您只能将部门inf附加到选定的视图并以有效的方式缓存结果(将请求代理到数据库)如果你想):

def department_context_processor(request):
    if hasattr(request, 'view_name'):
        if request.view_name == 'department_view1' or request.view_name == 'department_view2':
            departments = cache.get('department_'+str(request.user), None)
            if departments is None:
                departments = Department.objects.filter(user=request.user)
                cache.set('department_'+str(request.user), departments, 60*60)
            if departments:
                return {
                    'departments': departments
                }
    return {}