Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在用户使用中间件注销时删除用户_Python_Django_Signals_Middleware - Fatal编程技术网

Python 如何在用户使用中间件注销时删除用户

Python 如何在用户使用中间件注销时删除用户,python,django,signals,middleware,Python,Django,Signals,Middleware,我正在使用下面的中间件生成当前登录用户的列表。我遇到的问题是如何在用户注销后自动将其从online\u now和online\u now\u id中删除。我曾尝试使用信号,但没有成功…非常感谢任何帮助 from django.core.cache import cache from django.conf import settings from django.contrib.auth.models import User from django.utils.deprecation import

我正在使用下面的中间件生成当前登录用户的列表。我遇到的问题是如何在用户注销后自动将其从
online\u now
online\u now\u id
中删除。我曾尝试使用信号,但没有成功…非常感谢任何帮助

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)

您可以为此使用套接字,否则它不会真正在线显示
用户

如果没有套接字,它将不会如此精确,但以下是您可以分步骤执行的操作:

  • 为用户创建最后一个活动(日期时间)字段。(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()
    
这就是你所需要的

要查询在线用户(不是精确查询,只是一个示例):


这里最大的问题是概念上的;没有办法知道某人何时注销,因为人们不一定要注销。他们导航到另一个站点,或者关闭页面,或者让电脑进入睡眠状态……我同意丹尼尔的观点。最好使用web套接字来确定用户是否在线(至少在一些后台选项卡中)@Daniel与会话_EXPIRE _在_BROWSER _closeset(浏览器)(关闭集)之间是否存在上述问题我不确定这会有什么帮助。会话cookie可能已经过期,但服务器仍然无法知道这一点。
User.objects.filter(activities__last_activity__gte=timezone.now() - timedelta(seconds=30))