如何获取经过身份验证的用户列表?

时间:2010-04-27 16:33:45

标签: django authentication

我想显示经过身份验证的用户列表。

在文档上:http://docs.djangoproject.com/en/dev/topics/auth/

  

班级模特。用户
  is_authenticated()¶
      始终返回True。这是一种判断用户是否已通过身份验证的方法。 ...

您可以在模板方面知道当前用户是否经过身份验证:

  

{%if user.is_authenticated%}          {%endif%}

但我没有找到获取经过身份验证的用户列表的方式。

有什么想法吗?

4 个答案:

答案 0 :(得分:64)

与rz的答案一致,您可以在Session模型中查询未过期的会话,然后将会话数据转换为用户。一旦你有了它,你可以把它变成一个模板标签,可以在任何给定的页面上呈现列表。

(这都是未经测试的,但希望接近工作)。

获取所有已登录的用户...

from django.contrib.auth.models import User
from django.contrib.sessions.models import Session
from django.utils import timezone

def get_all_logged_in_users():
    # Query all non-expired sessions
    # use timezone.now() instead of datetime.now() in latest versions of Django
    sessions = Session.objects.filter(expire_date__gte=timezone.now())
    uid_list = []

    # Build a list of user ids from that query
    for session in sessions:
        data = session.get_decoded()
        uid_list.append(data.get('_auth_user_id', None))

    # Query all logged in users based on id list
    return User.objects.filter(id__in=uid_list)

使用此功能,您可以创建一个简单的包含模板标记...

from django import template
from wherever import get_all_logged_in_users
register = template.Library()

@register.inclusion_tag('templatetags/logged_in_user_list.html')
def render_logged_in_user_list():
    return { 'users': get_all_logged_in_users() }

<强> logged_in_user_list.html

{% if users %}
<ul class="user-list">
    {% for user in users %}
    <li>{{ user }}</li>
    {% endfor %}
</ul>
{% endif %}

然后在您的主页面中,您只需在您喜欢的地方使用它......

{% load your_library_name %}
{% render_logged_in_user_list %}

修改

对于那些谈论2周持久性问题的人,我假设任何想要拥有“活跃用户”类型列表的人都会使用SESSION_EXPIRE_AT_BROWSER_CLOSE设置,但我知道这不是'总是这样。

答案 1 :(得分:7)

最可靠的解决方案只是您在用户登录或注销时存储的内容。我看到了这个解决方案,我觉得它值得分享。

models.py

class LoggedUser(models.Model):
    user = models.ForeignKey(User, primary_key=True)

    def __unicode__(self):
        return self.user.username

    def login_user(sender, request, user, **kwargs):
        LoggedUser(user=user).save()

    def logout_user(sender, request, user, **kwargs):
        try:
            u = LoggedUser.objects.get(user=user)
            u.delete()
        except LoggedUser.DoesNotExist:
            pass

    user_logged_in.connect(login_user)
    user_logged_out.connect(logout_user)

views.py

logged_users = LoggedUser.objects.all().order_by('username')

答案 2 :(得分:1)

没有简单的内置方法来做我想知道的事情。我会在last_login上尝试过期会话和过滤的组合。甚至可能为此写一个自定义经理。

答案 3 :(得分:1)

听起来与此解决方案类似,您可以创建自定义中间件来执行此操作。我在这里找到了很棒的OnlineNowMiddleware

你会得到这些;

  1. {{ request.online_now }} =&gt;显示所有在线用户列表。
  2. {{ request.online_now_ids }} =&gt;显示所有在线用户ID。
  3. {{ request.online_now.count }} =&gt;显示在线用户总数。
  4. 如何设置?

    创建文件middleware.py,其中settings.py的位置已保存,例如:

    projectname/projectname/__init__.py
    projectname/projectname/middleware.py
    projectname/projectname/settings.py
    

    然后按照这一行;

    from django.core.cache import cache
    from django.conf import settings
    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)
    

    最后更新MIDDLEWARE的{​​{1}}内部文件:

    projectname/projectname/settings.py

    对于其他情况,您还可以使用以下方式检查当前用户是否在线:

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.cache.UpdateCacheMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.cache.FetchFromCacheMiddleware',
        ....
        # Custom middleware
        'projectname.middleware.OnlineNowMiddleware',
    ]