如何在Django中的logout / relogin中保存和恢复会话数据?

时间:2014-09-08 13:49:28

标签: django

我正在建立一个学习网站,存储有关用户进度的各种数据。目前,我正在使用会话来执行此操作。我想要以下行为:

  1. 未注册的用户可以在以后返回该网站,该网站将记住他们的进度。
  2. 当用户创建帐户时,他们不会丢失有关已收集进度的任何数据。
  3. 当注册用户注销时,应隐藏其进度。
  4. 当注册用户重新登录时,应恢复其进度。
  5. 会话对行为1-3很有用,但在第4步,进度无法恢复。如果我理解Django如何正确处理会话,那么当用户注销时会破坏所有会话数据。当用户重新登录时,保存此数据并再次恢复的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

似乎没有最好的方法可以做到这一点,但我提出的解决方案效果很好所以我想我会分享它。

我创建了一个单独的表,用于永久存储注册用户的键/值对。理想情况下,您可能希望将数据存储为类似于django_sesssion表的序列化JSON,但简单的字符字段也可以工作:

class account_data(models.Model):
    username = models.CharField(max_length=30)
    key = models.CharField(max_length=30)
    value = models.CharField(max_length=30, null=True, blank=True)
    class Meta:
        unique_together = ("username", "key")

每次我想保存或检索键值对时,都会检查用户是否已登录。如果不是,则将数据保存到会话中。如果是,我将数据保存到account_data表。我构建了一些函数来处理这个问题:

from account_manager.models import account_data

def getSessionOrAccountData(request, key):
    if request.user.is_authenticated():
        username = request.user.username
        try:
            record = account_data.objects.get(username=username, key=key)
            return record.value
        except:
            return None
    else:
        if key in request.session.keys():
            return request.session[key]
        else:
            return None

def setSessionOrAccountData(request, key, value):
    if request.user.is_authenticated():
        username = request.user.username
        try:
            record = account_data.objects.get(username=username, key=key)
            record.value = value
            record.save()
        except account_data.DoesNotExist:
            record = account_data(username=username, key=key, value=str(value))
            record.save()
    else:
        request.session[key] = value

def deleteSessionOrAccountData(request, key):
    if request.user.is_authenticated():
        username = request.user.username
        account_data.objects.filter(username=username).filter(key=key).delete()
    else:
        del request.session[key]

最后,当用户创建新帐户时,我想将他们可能拥有的任何会话数据复制到account_data表。创建新用户帐户后立即运行以下代码:

# save all existing session data to new user account
for key in request.session.keys():
    record = account_data(username=request.POST['username'], 
                                  key=key, 
                                  value=str(request.session[key]))
    record.save()