How to get the list of the authenticated users?

前端 未结 4 740
温柔的废话
温柔的废话 2020-11-29 17:14

I would like to display the list of the authenticated users.

On the documentation: http://docs.djangoproject.com/en/dev/topics/auth/

class mo

相关标签:
4条回答
  • 2020-11-29 17:50

    Going along with rz's answer, you could query the Session model for non-expired sessions, then turn the session data into users. Once you've got that you could turn it into a template tag which could render the list on any given page.

    (This is all untested, but hopefully will be close to working).

    Fetch all the logged in users...

    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)
    

    Using this, you can make a simple inclusion template tag...

    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 %}
    

    Then in your main page you can simply use it where you like...

    {% load your_library_name %}
    {% render_logged_in_user_list %}
    

    EDIT

    For those talking about the 2-week persistent issue, I'm assuming that anyone wanting to have an "active users" type of listing will be making use of the SESSION_EXPIRE_AT_BROWSER_CLOSE setting, though I recognize this isn't always the case.

    0 讨论(0)
  • 2020-11-29 18:00

    There is no easy, built-in way to do what you want that I know of. I'd try a combination of expiring sessions and filtering on last_login. Maybe even write a custom manager for that.

    0 讨论(0)
  • 2020-11-29 18:09

    Most reliable solution would only be the something you store when user logs in or logs out. I saw this solution and i think its worth sharing.

    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')
    
    0 讨论(0)
  • 2020-11-29 18:12

    Sounds similiar with this solution, you can create a custom middleware to do it. I found awesome OnlineNowMiddleware here.

    Where you will get these;

    1. {{ request.online_now }} => display all list of online users.
    2. {{ request.online_now_ids }} => display all online user ids.
    3. {{ request.online_now.count }} => display total online users.

    How to set up?

    Create file middleware.py where location of settings.py has been saved, eg:

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

    Then following this lines;

    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)
    

    Finally update your MIDDLEWARE inside file of 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',
    ]
    

    For other condition, you can also check the current user is online or not with:

    {% if request.user in request.online_now %}
        {# do stuff #}
    {% endif %}
    
    0 讨论(0)
提交回复
热议问题