Django: get last user visit date
Example model:
class User(models.Model):
last_visit = models.DateTimeField(...)
...
Example middleware which will be executed for all logged-in users:
from django.utils.timezone import now
class SetLastVisitMiddleware(object):
def process_response(self, request, response):
if request.user.is_authenticated():
# Update last visit time after request finished processing.
User.objects.filter(pk=request.user.pk).update(last_visit=now())
return response
Add the new middleware to Your settings.py:
MIDDLEWARE_CLASSES = (
...
'path.to.your.SetLastVisitMiddleware',
...
)
Warning: not tested, but doesn't require external packages to be installed and it's only 5 lines of code.
See more in the docs about Middleware and custom user models (since Django 1.5)
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 <user profile path> 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:
- How you define
settings.LAST_ACTIVITY_INTERVAL_SECS
determine what constitutes the interval of non-activity considered to be a new login. - This updates a "UserProfile" object which I have 1:1 with my User objects, but you can update any object you please.
- Make sure to include this in
settings.MIDDLEWARE_CLASSES
. - Note this middleware uses
process_request
notprocess_response
otherwise depending on middleware order,APPEND_SLASH
may causerequest.user
to be unavailable as discussed: Django: WSGIRequest' object has no attribute 'user' on some pages?