【问题标题】:How to check whether a user is online in django template?如何在 django 模板中检查用户是否在线?
【发布时间】:2015-06-22 05:07:51
【问题描述】:

在模板中,当我使用

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

用户结果总是在线,即使他们已经退出了一段时间。所以我想知道如何正确检查在线用户?

【问题讨论】:

    标签: django django-templates django-sessions


    【解决方案1】:

    ‌感谢this 优秀的博文,稍作修改,我想出了一个更好的解决方案,它使用内存缓存,因此每个请求的延迟更少:

    在models.py中添加:

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

    并将这些方法添加到 userprofile 类中:

    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 
    

    在 userprofile 文件夹中添加这个 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)
    

    在 settings.py 中添加 'userprofile.middleware.ActiveUserMiddleware',MIDDLEWARE_CLASSES 并添加:

        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
    

    在 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>
    

    就是这样!

    在控制台测试缓存,确保memcache正常工作:

    $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'
    

    【讨论】:

    • 更改为新版本添加这些: from django.utils.deprecation import MiddlewareMixin class ActiveUserMiddleware(MiddlewareMixin): .....and request.user.is_authenticated: 而不是 request.user.is_authenticated() :
    • 嗨@Jand :) 希望你一切都好!你能看看我的问题吗? stackoverflow.com/questions/63668786/…
    【解决方案2】:

    正如documentation 所说:

    尽管通常您会检查 request.user 上的 is_autheticated 属性以了解它是否已由 AuthenticationMiddleware(代表当前登录的用户)填充,但您应该知道该属性对于任何 User 实例都是 True。

    所以要检查用户是否在线,我会这样做:

    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()
    

    然后在您的模板中检查用户是否在线:

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

    不要忘记将用户实例返回到您的模板,以便 user.profile.is_online 工作。

    【讨论】:

    • 谢谢@ahtusham,我忘记了信号的存在。谢谢 !它更简单、更强大。
    【解决方案3】:

    您可以为每个用户设置一个整数字段,表示用户当前登录的会话数。您可以在用户每次登录某处时将其增加 1,并在用户在某处注销时将其减少 1。

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

    这是解决此问题的简单方法。您可以通过 ajax 请求定期刷新此数据。

    【讨论】:

    • 能否详细说明如何通过ajax请求刷新页面?
    • @Randi:您可以有一个 url,您可以在其中发送用户名作为参数并获取数据以了解用户是否登录。然后,刷新该特定 div 上的数据
    • 此解决方案的可扩展性如何?
    • @Randi 我无法对此发表评论,直到我进一步了解您的实现是什么以及您必须检查多少用户
    【解决方案4】:

    首先通过运行安装 django-online-users

    pip install django-online-users
    

    然后在你的 settings.py 中

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

    那么在你看来

    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"}`
    

    例如将上下文传递给您的模板

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

    这将输出过去 60 秒内活跃且在线的用户

    【讨论】:

      【解决方案5】:

      Django documentation 中描述了用户似乎始终在线的原因:

      is_authenticated()

      • 总是返回 True ...这是一种判断用户是否已通过身份验证的方法。这并不意味着任何权限,也不会检查用户是否处于活动状态或拥有有效的会话。

      有很多方法可以实现这一点,但没有一种是“内置”的。

      This question covers the last activity time of a user,您可以使用它来检查用户在过去几分钟内是否处于活动状态。

      Alternatively, you can query the Session table 检查用户是否有活动会话,但如果会话超时时间过长,这可能不准确。

      【讨论】:

        【解决方案6】:

        是的。但是检查用户是否登录的正确方法是使用:request.user.is_authenticated。如果此人已登录,则返回 True,否则返回 False。

        例如:

        在模板中:

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

        在视图中将请求传递到模板中。

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

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-07
        • 2019-09-01
        • 2021-02-26
        • 1970-01-01
        • 2011-11-20
        • 2014-05-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多