首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django -会议管理

Django -会议管理
EN

Stack Overflow用户
提问于 2019-03-08 13:09:38
回答 2查看 763关注 0票数 0

我希望防止同一个用户帐户在我的应用程序中有多个活动会话,并遵循this question的回答。

我在我的models.py中实现了这一点

代码语言:javascript
复制
from django.conf import settings
from django.db import models
from django.contrib.sessions.models import Session

class UserSession(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    session = models.OneToOneField(Session, on_delete=models.CASCADE)


from django.contrib.auth import user_logged_in
from django.dispatch.dispatcher import receiver

@receiver(user_logged_in)
def remove_other_sessions(sender, user, request, **kwargs):
    # remove other sessions
    Session.objects.filter(usersession__user=user).delete()

    # save current session
    request.session.save()

    # create a link from the user to the current session (for later removal)
    UserSession.objects.get_or_create(
        user=user,
        session=Session.objects.get(pk=request.session.session_key)
    )

不过,我注意到了一种奇怪的行为。

如果我用一个帐户登录,然后打开一个匿名窗口并使用相同的凭据登录,则第一个帐户将被注销(这正是我想要的)。

但是,如果我用一个帐户登录,然后关闭浏览器,下次我要登录时,我会在行中得到一个错误:

代码语言:javascript
复制
# save current session
request.session.save()

使用以下跟踪(没有太多信息.):

UpdateError at / 没有提供异常消息

控制台日志显示错误来自

代码语言:javascript
复制
django.contrib.sessions.backends.base.UpdateError

在此之后,如果刷新页面,则可以成功登录。

对可能发生的事有什么见解吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-08 13:43:13

您正在接收该错误,因为数据库中不再有要更新的会话,您已经删除了所有活动会话(在此之上2行)。要解决这个问题,只需在清除当前活动会话时忽略它们:

代码语言:javascript
复制
@receiver(user_logged_in)
def remove_other_sessions(sender, user, request, **kwargs):
    # remove other sessions
    old_sessions = Session.objects.filter(usersession__user=user)
    if request.session.session_key:
        old_sessions = old_sessions.exclude(session_key=request.session.session_key)
    old_sessions.delete()

    # save current session
    request.session.save()

    # create a link from the user to the current session (for later removal)
    UserSession.objects.get_or_create(
        user=user,
        session=Session.objects.get(pk=request.session.session_key)
    )
票数 1
EN

Stack Overflow用户

发布于 2020-02-12 09:25:29

GwynBleidD的回答很好!但这里有个小虫子:

代码语言:javascript
复制
if request.session.session_key:
        old_sessions = old_sessions.exclude(session_key=request.session.session_key)

应写为:

代码语言:javascript
复制
if request.session.session_key:
        old_sessions = old_sessions.exclude(session_key=request.session.session_key).delete()
else:
    old_sessions.delete()

否则,当您第二次尝试在同一台计算机上登录时,将出现错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55063904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档