How to check whether a user is online in django template?

后端 未结 6 1035
终归单人心
终归单人心 2020-12-05 09:16

In template, when I use

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

the users turn out to be always onli

相关标签:
6条回答
  • 2020-12-05 09:23

    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})
    
    0 讨论(0)
  • 2020-12-05 09:24

    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.

    0 讨论(0)
  • 2020-12-05 09:31

    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

    0 讨论(0)
  • 2020-12-05 09:35

    ‌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'
    
    0 讨论(0)
  • 2020-12-05 09:38

    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.

    0 讨论(0)
  • 2020-12-05 09:39

    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.

    0 讨论(0)
提交回复
热议问题