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
Here's a middleware that will keep track of user last activity and count separated by intervals of time. Using the interval creates discrete "sessions" which can be tracked/counted along with the benefit of minimizing writes to the database.
Every time an auth user performs a request, will hit the cache to find their last activity, and then update the cache with a new timestamp. If the activity has had a gap of at least "interval" time, then it will update the database timestamp.
from datetime import timedelta as td
from django.utils import timezone
from django.conf import settings
from django.db.models.expressions import F
from import UserProfile
class LastUserActivityMiddleware(object):
KEY = "last-activity"
def process_request(self, request):
if request.user.is_authenticated():
last_activity = request.session.get(self.KEY)
# If key is old enough, update database.
too_old_time = timezone.now() - td(seconds=settings.LAST_ACTIVITY_INTERVAL_SECS)
if not last_activity or last_activity < too_old_time:
UserProfile.objects.filter(user=request.user.pk).update(
last_login=timezone.now(),
login_count=F('login_count') + 1)
request.session[self.KEY] = timezone.now()
return None
Comments:
settings.LAST_ACTIVITY_INTERVAL_SECS determine what constitutes the interval of non-activity considered to be a new login.settings.MIDDLEWARE_CLASSES.process_request not process_response otherwise depending on middleware order, APPEND_SLASH may cause request.user to be unavailable as discussed: Django: WSGIRequest' object has no attribute 'user' on some pages?