17

django's User model has a last_login field, which is great if all the users were to log out each time they leave the site, but what if they don't?

How can I track when a user who never logged out and his activity on the site?

Aamir Rind
  • 38,793
  • 23
  • 126
  • 164
la_f0ka
  • 1,773
  • 3
  • 23
  • 44

3 Answers3

27

You need to have the last_activity field in the user profile (or custom user model). This field will be updated on every request. To achieve this you need to have custom middleware:

profiles/middleware.py:

from django.utils import timezone

from myproject.profiles.models import Profile


class UpdateLastActivityMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        assert hasattr(request, 'user'), 'The UpdateLastActivityMiddleware requires authentication middleware to be installed.'
        if request.user.is_authenticated():
            Profile.objects.filter(user__id=request.user.id) \
                           .update(last_activity=timezone.now())

Add this middleware in your setting file:

MIDDLEWARE_CLASSES = (
    # other middlewares
    'myproject.profiles.middleware.UpdateLastActivityMiddleware',
)
Aamir Rind
  • 38,793
  • 23
  • 126
  • 164
  • 10
    It seems like this would result in a very large number of writes the database, potentially impacting performance. For something more efficient, consider writing the last activity into a cache and then periodically into the database. I believe that's what https://bitbucket.org/ferranp/django-last-seen probably does. – John Lehmann Aug 20 '16 at 18:04
  • 10
    Although this answers the question, this broke my Django installation when the amount of users increased. It took some hours to figure out, so I hope this post saves someone some hours! – gabn88 Sep 08 '16 at 12:42
3

i think in 2022 this will satisfy what you need also i did this and worked for me but the answer didnt.

put LastActivityTraceMiddleware after AuthenticationMiddleware in settings.py.

from django.utils.timezone import now
from .... import MemberEntity


class LastActivityTraceMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)

        member: MemberEntity = request.user
        if member.is_authenticated:
            member.last_login = now()
            member.save()
        return response
Samurai jk
  • 41
  • 4
2

I know the question is old ... and surely it has already been solved ... but here is my contribution ... In new versions of django you can use:

"Session Time" -> Used in configuration file. "settings.py"

If the user closes the browser, the session ends and must be logged in again ...
SESSION_EXPIRE_AT_BROWSER_CLOSE = True

If the user does not close the browser, you can set a time limit for the session ...
SESSION_COOKIE_AGE = 60 * 60 

For "SESSION_COOKIE_AGE" if I remember correctly it's defined in seconds. You can see more here... Recommended reading is also django's own documentation about sessions...