Django的设计里,Session的保存是借助Cookie的,Cookie的保存默认有两种周期,浏览器生命周期和14天周期。这两者的选择在settings.py里面的一个参数,设成True就是前者,设成False就是后者。但是,我们通常的需求是用户登录的时候可以选择是否记住登录,如果不选就是前者,如果选中,就使用后者,但是Django却没有留下这个接口。
在我以前的文章里面,是通过直接修改Django的源代码,改了它的sessionMiddleware来解决的,今天在浏览它的google group的时候,终于找到了一个比较正规的方法。其实其原理跟我那个方法是完全一样的,修改sessionMiddleware,让它在设置Cookie之前从当前的session里面读取一个值,看看是否要记住密码,从而控制生成哪一个周期的Cookie。
但是他的做法就比我要高明了,我的做法直接修改了Django的源代码,所以导致每次升级的时候会很麻烦,因为会覆盖以前的修改。但是他的做法是自己重新写了一个sessionMiddleware,基本上,这个文件应该就是直接把原来的拷了出来,然后做修改。只要在settings文件中指定这个middleware的类,让你的项目使用自己的这个就可以了。这样,系统自己的就完全被忽略掉了。
想来想去,还是把代码附上吧,以防万一:
 1Django:更简单的实现记住密码功能from django.conf import settings
 2Django:更简单的实现记住密码功能from django.contrib.sessions.models import Session
 3Django:更简单的实现记住密码功能from django.contrib.sessions.middleware import SessionWrapper
 4Django:更简单的实现记住密码功能from django.utils.cache import patch_vary_headers
 5Django:更简单的实现记住密码功能import datetime
 6Django:更简单的实现记住密码功能
 7Django:更简单的实现记住密码功能class DualSessionMiddleware(object):
 8Django:更简单的实现记住密码功能    """Session middleware that allows you to turn individual browser-length 
 9Django:更简单的实现记住密码功能    sessions into persistent sessions and vice versa.
10Django:更简单的实现记住密码功能    
11Django:更简单的实现记住密码功能    This middleware can be used to implement the common "Remember Me" feature
12Django:更简单的实现记住密码功能    that allows individual users to decide when their session data is discarded.
13Django:更简单的实现记住密码功能    If a user ticks the "Remember Me" check-box on your login form create
14Django:更简单的实现记住密码功能    a persistent session, if they don't then create a browser-length session.
15Django:更简单的实现记住密码功能    
16Django:更简单的实现记住密码功能    This middleware replaces SessionMiddleware, to enable this middleware:
17Django:更简单的实现记住密码功能    - Add this middleware to the MIDDLEWARE_CLASSES setting in settings.py, 
18Django:更简单的实现记住密码功能      replacing the SessionMiddleware entry.
19Django:更简单的实现记住密码功能    - In settings.py add this setting: 
20Django:更简单的实现记住密码功能      PERSISTENT_SESSION_KEY = 'sessionpersistent'
21Django:更简单的实现记住密码功能    - Tweak any other regular SessionMiddleware settings (see the sessions doc),
22Django:更简单的实现记住密码功能      the only session setting that's ignored by this middleware is 
23Django:更简单的实现记住密码功能      SESSION_EXPIRE_AT_BROWSER_CLOSE. 
24Django:更简单的实现记住密码功能      
25Django:更简单的实现记住密码功能    Once this middleware is enabled all sessions will be browser-length by
26Django:更简单的实现记住密码功能    default.
27Django:更简单的实现记住密码功能    
28Django:更简单的实现记住密码功能    To make an individual session persistent simply do this:
29Django:更简单的实现记住密码功能    
30Django:更简单的实现记住密码功能    session[settings.PERSISTENT_SESSION_KEY] = True
31Django:更简单的实现记住密码功能    
32Django:更简单的实现记住密码功能    To make a persistent session browser-length again simply do this:
33Django:更简单的实现记住密码功能    
34Django:更简单的实现记住密码功能    session[settings.PERSISTENT_SESSION_KEY] = False
35Django:更简单的实现记住密码功能    """
36Django:更简单的实现记住密码功能    
37Django:更简单的实现记住密码功能    def process_request(self, request):
38Django:更简单的实现记住密码功能        request.session = SessionWrapper(request.COOKIES.get(settings.SESSION_COOKIE_NAME, None))
39Django:更简单的实现记住密码功能
40Django:更简单的实现记住密码功能    def process_response(self, request, response):
41Django:更简单的实现记住密码功能        # If request.session was modified, or if response.session was set, save
42Django:更简单的实现记住密码功能        # those changes and set a session cookie.
43Django:更简单的实现记住密码功能        patch_vary_headers(response, ('Cookie',))
44Django:更简单的实现记住密码功能        try:
45Django:更简单的实现记住密码功能            modified = request.session.modified
46Django:更简单的实现记住密码功能        except AttributeError:
47Django:更简单的实现记住密码功能            pass
48Django:更简单的实现记住密码功能        else:
49Django:更简单的实现记住密码功能            if modified or settings.SESSION_SAVE_EVERY_REQUEST:
50Django:更简单的实现记住密码功能                session_key = request.session.session_key or Session.objects.get_new_session_key()
51Django:更简单的实现记住密码功能                
52Django:更简单的实现记住密码功能                if not request.session.get(settings.PERSISTENT_SESSION_KEY, False):
53Django:更简单的实现记住密码功能                    # session will expire when the user closes the browser
54Django:更简单的实现记住密码功能                    max_age = None
55Django:更简单的实现记住密码功能                    expires = None
56Django:更简单的实现记住密码功能                else:
57Django:更简单的实现记住密码功能                    max_age = settings.SESSION_COOKIE_AGE
58Django:更简单的实现记住密码功能                    expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE), "%a, %d-%b-%Y %H:%M:%S GMT")
59Django:更简单的实现记住密码功能                
60Django:更简单的实现记住密码功能                new_session = Session.objects.save(session_key, 
61Django:更简单的实现记住密码功能                                                   request.session._session,
62Django:更简单的实现记住密码功能                                                   datetime.datetime.now() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE))
63Django:更简单的实现记住密码功能                response.set_cookie(settings.SESSION_COOKIE_NAME, session_key,
64Django:更简单的实现记住密码功能                                    max_age = max_age, expires = expires, 
65Django:更简单的实现记住密码功能                                    domain = settings.SESSION_COOKIE_DOMAIN,
66Django:更简单的实现记住密码功能                                    secure = settings.SESSION_COOKIE_SECURE or None)
67Django:更简单的实现记住密码功能        return response
68Django:更简单的实现记住密码功能

相关文章: