Как удалить пользователей при выходе из системы с помощью промежуточного программного обеспечения - PullRequest
0 голосов
/ 21 мая 2018

Я использую промежуточное программное обеспечение ниже, чтобы создать список пользователей, вошедших в данный момент.У меня проблема в том, как автоматически удалять пользователей из online_now и online_now_ids, когда они вышли из системы.Я пытался использовать сигналы, но безуспешно ... любая помощь очень ценится

from django.core.cache import cache
from django.conf import settings
from django.contrib.auth.models import User
from django.utils.deprecation import MiddlewareMixin
from django.dispatch import receiver
from django.contrib.auth.signals import user_logged_out
#Set Environment variables for settings.py

ONLINE_THRESHOLD = getattr(settings, 'ONLINE_THRESHOLD', 30*1)
ONLINE_MAX = getattr(settings, 'ONLINE_MAX', 50)
CACHE_MIDDLEWARE_SECONDS = getattr(settings, 'CACHE_MIDDLEWARE_SECONDS', 10)

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 logged into the website.
    User ID's are available as `online_now_ids` on the request object,
    and their corresponding users are available lazzily as the `online_now`
    property on the request object
    """

    def process_request(self, request):
        #Get the index 
        uids = cache.get('online-now', [])

        #multiget on individual 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 user is authenticated add id to list
        if request.user.is_authenticated():
            uid = request.user.id
            #if uid in list bump to top
            # and remove 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 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)

1 Ответ

0 голосов
/ 21 мая 2018

Вы можете использовать сокеты для этого, иначе это НЕ ДЕЙСТВИТЕЛЬНО покажет online пользователей.

Без сокетов это будет не так точно, но вот что вы можете сделать пошагово:

  • Создать поле последнего действия (дата / время) для пользователя.(OneOnOne или любым другим способом, которым вы хотите сохранить эти отношения)

  • В промежуточном программном обеспечении измените код, чтобы обновить последнее поле активности пользователя.

    if request.user.is_authenticated():
        user_activity, c = UserActivity.objects.get_or_create(user=request.user)
        user_activity.last_activity = timezone.now()
        user_activity.save()
    

Это все, что вам нужно.

Для запроса онлайн-пользователей (не точный запрос, просто пример):

User.objects.filter(activities__last_activity__gte=timezone.now() - timedelta(seconds=30))
...