我正在使用下面的中间件生成当前登录用户的列表。我遇到的问题是如何在用户退出时自动从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)
答案 0 :(得分:0)
您可以为此使用套接字,否则它将不会真正显示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))