[Fixed]-How to check whether a user is online in django template?

25👍

‌Thanks this excellent blog post, with slight modifications, I came up with a better solution, which uses memcache, hence less delay per request:

in models.py add:

from django.core.cache import cache 
import datetime
from myproject import settings

and add these method the userprofile class:

def last_seen(self):
    return cache.get('seen_%s' % self.user.username)

def online(self):
    if self.last_seen():
        now = datetime.datetime.now()
        if now > self.last_seen() + datetime.timedelta(
                     seconds=settings.USER_ONLINE_TIMEOUT):
            return False
        else:
            return True
    else:
        return False 

in userprofile folder add this middleware.py

import datetime
from django.core.cache import cache
from django.conf import settings

class ActiveUserMiddleware:

    def process_request(self, request):
        current_user = request.user
        if request.user.is_authenticated():
            now = datetime.datetime.now()
            cache.set('seen_%s' % (current_user.username), now, 
                           settings.USER_LASTSEEN_TIMEOUT)

in settings.py add 'userprofile.middleware.ActiveUserMiddleware', to MIDDLEWARE_CLASSES and also add:

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',              
        }
    }

# Number of seconds of inactivity before a user is marked offline
USER_ONLINE_TIMEOUT = 300

# Number of seconds that we will keep track of inactive users for before 
# their last seen is removed from the cache
USER_LASTSEEN_TIMEOUT = 60 * 60 * 24 * 7

and in profile.html:

 <table>
   <tr><th>Last Seen</th><td>{% if profile.last_seen %}{{ profile.last_seen|timesince }}{% else %}awhile{% endif %} ago</td></tr>
   <tr><th>Online</th><td>{{ profile.online }}</td></tr>
 </table>

That’s it!

To test cache in the console, to make sure that memcache works fine:

$memcached -vv
$ python manage.py shell
>>> from django.core.cache import cache
>>> cache.set("foo", "bar")
>>> cache.get("foo")
'bar'
>>> cache.set("foo", "zaq")
>>> cache.get("foo")
'zaq'
👤Jand

8👍

As the documentation says:

Even though normally you will check is_autheticated attribute on request.user to find out whether it has been populated by the AuthenticationMiddleware (representing the currently logged-in user), you should know this attribute is True for any User instance.

So to check if user is online I would do something like this:

models.py

class Profile(models.Model):
    user = models.OneToOneField(User, related_name='profile')           
    is_online = models.BooleanField(default=False)

views.py

from django.contrib.auth.signals import user_logged_in, user_logged_out
from django.dispatch import receiver    

@receiver(user_logged_in)
def got_online(sender, user, request, **kwargs):    
    user.profile.is_online = True
    user.profile.save()

@receiver(user_logged_out)
def got_offline(sender, user, request, **kwargs):   
    user.profile.is_online = False
    user.profile.save()

And then in your template you would check if user is online:

{% if user.profile.is_online %}
    Online
{% else %}
    Offline
{% endif %}

Don’t forget to return user instance to your template in order for user.profile.is_online to work.

2👍

You can have an integer field for each user saying the number of sessions the user has logged in currently. You can increase that by 1 every time the user logs in somewhere, and reduce it by 1 when the user logs out somewhere.

{% if topic.creator.login_count %}
Online
{% else %}
Offline
{% endif %}

This is a simple way to solve this problem. You can refresh this data through an ajax request periodically.

2👍

first install django-online-users by running

pip install django-online-users

then in your settings.py

INSTALLED_APPS = [
...
'online_users',] 
MIDDLEWARE_CLASSES = (
...
'online_users.middleware.OnlineNowMiddleware',)

Then in your views

import online_users.models



def see_users(self):

  user_status = online_users.models.OnlineUserActivity.get_user_activities(timedelta(seconds=60))
  users = (user for user in  user_status)
  context = {"online_users"}`

Pass the context to your template for example

{% for user in users %}
  {{user.user}}
{% endfor %}

This will output the users who have been active and online for the last 60 seconds

1👍

The reason a user appears to always be online is described in the Django documentation:

is_authenticated()

  • Always returns True … This is a way to tell if the user has been authenticated. This does not imply any permissions, and doesn’t check if the user is active or has a valid session.

There are a number of ways you could achieve this, but none are "build-in".

This question covers the last activity time of a user, and you could use that to check if a user was active in the past few minutes.

Alternatively, you can query the Session table to check if the user has an active session, but this may be inaccurate if you have long session timeouts.

1👍

Yes it does. But the correct way to check if a user is logged in or not is to use : request.user.is_authenticated. This will return True if the person is logged in other wise False.

eg:

in the template:

{% if request.user.is_authenticated ==True %}
      do something awesome.

in views pass request into the template.

return render('url/filename.html',{'any variable name':request})

Leave a comment