我目前在我的一个系统中实施的一个很好的解决方案是,如果您希望会话在每个请求上自动更新,那么您可以编写中间件来更改会话的到期时间,以便在您需要的任何视图中进行扩展。
注意:此解决方案确实为每个请求进行 2 次数据库查询。 1 用于读取,1 用于更新。这是一个非常小的开销(使用调试工具栏最多调用通常只有几个 MS),但它是存在的。
例如:
from functools import wraps
from [project] import settings
class CookieMiddleware(object):
"""
This middleware sets the login cookie to update timeout on every request
"""
def __init__(self, get_response):
self.get_response = get_response
@staticmethod
def process_view(request, view_func, args, kwargs):
# ensure that we don't want to exclude this from running
if getattr(view_func, 'cookie_not_important', False):
print('cookie not important:', view_func.__name__)
return None
# the cookie is set, let's now set a new expire time to 30 minutes from now
print('cookie expiry changed:', view_func.__name__)
# it is probably smartest to grab this value back from settings
expire_time = settings.SESSION_COOKIE_AGE
# expire_time = 30 * 60
request.session.set_expiry(expire_time)
return view_func(request, *args, **kwargs)
def __call__(self, request):
response = self.get_response(request)
return response
def cookie_not_important(view_func):
"""
Decorator used to allow the exclusion of the cookie time being reset
:param view_func: The view being wrapped
:return:
"""
def view_being_wrapped(*args, **kwargs):
return view_func(*args, **kwargs)
view_being_wrapped.cookie_not_important = True
return wraps(view_func)(view_being_wrapped)
现在您可以登录并点击任何未被@cookie_not_important 包裹的视图,过期时间将根据settings.py 中的当前值重置
为了完整起见,视图看起来是这样包裹的:
from django.urls import reverse
@cookie_not_important
def logout(request):
del request.session
return redirect(reverse('some_view_name'))