Skip to content

Instantly share code, notes, and snippets.

@agusmakmun
Forked from dfalk/onlinenow.py
Last active December 8, 2022 02:31
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save agusmakmun/c0c81ee21245578b1f13c003d1def401 to your computer and use it in GitHub Desktop.
Save agusmakmun/c0c81ee21245578b1f13c003d1def401 to your computer and use it in GitHub Desktop.
django online users, usage: {{ request.online_now }} or {{ request.online_now_ids }}, usage: https://python.web.id/blog/django-count-online-users/
from django.conf import settings
from django.core.cache import cache
from django.contrib.auth.models import User
from django.utils.deprecation import MiddlewareMixin
ONLINE_THRESHOLD = getattr(settings, 'ONLINE_THRESHOLD', 60 * 15)
ONLINE_MAX = getattr(settings, 'ONLINE_MAX', 50)
def get_online_now(self):
return User.objects.filter(id__in=self.online_now_ids or [])
class OnlineNowMiddleware(MiddlewareMixin):
"""
Maintains a list of users who have interacted with the website recently.
Their user IDs are available as ``online_now_ids`` on the request object,
and their corresponding users are available (lazily) as the
``online_now`` property on the request object.
"""
def process_request(self, request):
# First get the index
uids = cache.get('online-now', [])
# Perform the multiget on the individual online uid keys
online_keys = ['online-%s' % (u,) for u in uids]
fresh = cache.get_many(online_keys).keys()
online_now_ids = [int(k.replace('online-', '')) for k in fresh]
# If the user is authenticated, add their id to the list
if request.user.is_authenticated:
uid = request.user.id
# If their uid is already in the list, we want to bump it
# to the top, so we remove the earlier entry.
if uid in online_now_ids:
online_now_ids.remove(uid)
online_now_ids.append(uid)
if len(online_now_ids) > ONLINE_MAX:
del online_now_ids[0]
# Attach our modifications to the request object
request.__class__.online_now_ids = online_now_ids
request.__class__.online_now = property(get_online_now)
# Set the new cache
cache.set('online-%s' % (request.user.pk,), True, ONLINE_THRESHOLD)
cache.set('online-now', online_now_ids, ONLINE_THRESHOLD)
@davidshumway
Copy link

What is the purpose of ONLINE_MAX = getattr(settings, 'ONLINE_MAX', 50)? It only counts 50 users?

@residentcode
Copy link

Could you make it works for session instrad of cache .
cache is not an option for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment