In Django, we can get the time user last logged in by using Auth.User.last_login. That is only updated when the user logs in using his username/password. Supp
The solution of @John Lehmann is wonderful. However, it requires using specific cache-based sessions settings to avoid database write on each request.
There are two options in cache-based sessions, backends.cache or backends.cached_db. The second one is a write-through cache, i.e. each modification to session data is written on both the database as well as cache. This provides persistency across restarts.
I have re-written the above to explicitly use the cache function and avoid many database writes.
from django.core.cache import cache
from django.utils import timezone
# other user model import
def last_visit_middleware(get_response):
def middleware(request):
"""
Save the time of last user visit
"""
response = get_response(request)
if request.session.session_key:
key = "recently-seen-{}".format(request.session.session_key)
recently_seen = cache.get(key)
# is_authenticated hits db as it selects user row
# so we will hit it only if user is not recently seen
if not recently_seen and request.user.is_authenticated:
UserAccount.objects.filter(id=request.user.id) \
.update(last_visit=timezone.now())
visit_time = 60 * 30 # 30 minutes
cache.set(key, 1, visit_time)
return response
return middleware
The records the time of last arrival or last visit. It does not record the time of last exit or "last seen".