You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Django的在线测验应用多用户访问隔离及并发处理咨询

问题根源与解决方案

核心问题

你现在的测验进度(当前第几题)肯定是存在全局变量里了,所有用户的请求都会读写这个变量,自然会互相干扰。这和用runserver、Apache还是Docker无关——部署方式不解决用户状态隔离的逻辑问题。

正确的用户状态隔离方案

1. 使用Django Session存储临时测验状态

这是Web开发处理用户专属临时数据的标准做法,完全符合最佳实践。Django的Session默认存在数据库中,每个用户有唯一的sessionid(通过Cookie传递),状态完全隔离。

示例代码思路:

  • 用户开始测验时,初始化Session:
    def start_quiz(request):
        request.session['current_question'] = 1
        request.session['quiz_id'] = 1  # 若存在多个测验
        # 其他初始化逻辑
        return render(request, 'quiz.html')
    
  • 用户答题后,更新Session中的进度:
    def submit_answer(request):
        current_q = request.session.get('current_question', 1)
        # 验证答案逻辑
        request.session['current_question'] = current_q + 1
        # 返回下一题数据
        return JsonResponse({'next_question': current_q + 1})
    
  • 每次加载题目时,从Session读取当前进度:
    def get_current_question(request):
        current_q = request.session.get('current_question', 1)
        question = Question.objects.get(id=current_q)
        return JsonResponse({'question': question.text})
    

2. 结合用户账号存储持久化进度(若有登录系统)

如果你的应用要求用户登录,建议把测验进度存在数据库的关联表中,这样用户即使关闭浏览器重新登录,也能继续之前的测验。

示例模型设计:

from django.db import models
from django.contrib.auth.models import User

class QuizProgress(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    quiz_id = models.IntegerField()
    current_question = models.IntegerField(default=1)
    completed = models.BooleanField(default=False)

每次用户操作时,更新这个表的记录即可,完全隔离每个用户的进度。

3. 前端本地存储(补充方案)

如果不需要后端跟踪进度,也可以把当前题存在前端的localStorage里,前端自己管理进度,提交答案时再传给后端。但这种方式不适合需要防作弊的场景,因为用户可以手动修改localStorage的值。

纠正你的错误思路

  • 为每个用户启动新线程:完全没必要。Web服务器本身就是多线程/多进程处理请求,每个请求都是独立的,问题出在你共享了全局状态,和线程无关。
  • 部署到Apache或Docker:这些只是部署环境,解决的是服务的运行和扩展问题,不解决用户状态隔离的核心问题——哪怕换了部署方式,全局变量还是会被所有用户共享。

内容的提问来源于stack exchange,提问作者Thomas Langer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:06:21