Django猜国旗游戏多用户/多标签页数据冲突问题求助
Django猜国旗游戏多用户/多标签页状态冲突解决方案
问题描述
我是Django新手,正在开发一款猜国旗网页游戏。点击主页的“play”按钮后,用户会进入一个页面,系统从数据库随机选出4个国家,其中只有一个是正确答案。但当其他用户打开网站或打开多个标签页时,分数会被重置,且所有用户的随机国家列表都会被重新生成,导致猜测永远无法正确。
原views.py代码:
context = {} context['submit'] = None context['countries_list'] = None score = [] score.clear() context['score'] = 0 def play(request): len_score = len(score) countries = Country.objects.all() real_choice = None if request.POST: get_guess = request.POST.get('guess') print(request.POST) if str(get_guess).casefold() == str(context['submit']).casefold(): score.append(1) else: score.clear() len_score = len(score) choices = random.sample(tuple(countries),4) real_choice = random.choice(choices) context['countries_list'] = choices context['submit'] = real_choice context['score'] = len_score return render (request, 'base/play.html', context)
问题根源
你把context、score这些状态变量定义在了视图函数外部,它们属于全局变量。Django的服务器会让所有请求共享这些全局变量,导致:
- 多个用户/标签页的请求会互相覆盖正确答案和选项列表,提交的猜测永远对应不上当前页面的题目
- 所有用户共用同一个
score列表,一个用户猜错会清空所有人的分数,新请求也会干扰旧请求的状态
修复方案
用Django的request.session存储用户专属状态,每个用户的会话数据是独立隔离的,不会互相干扰。重构后的代码如下:
def play(request): # 从会话获取当前分数,无则初始化为0 score = request.session.get('score', 0) countries = Country.objects.all() if request.POST: get_guess = request.POST.get('guess') # 从会话取出上一轮的正确答案用于验证 previous_correct = request.session.get('correct_answer') if str(get_guess).casefold() == str(previous_correct).casefold(): score += 1 else: score = 0 # 更新会话中的分数 request.session['score'] = score # 生成新的题目选项和正确答案 choices = random.sample(tuple(countries), 4) real_choice = random.choice(choices) # 把当前正确答案存入会话,供下一次提交验证 request.session['correct_answer'] = real_choice # 构建当前请求的上下文,每个请求独立生成 context = { 'countries_list': choices, 'score': score } return render(request, 'base/play.html', context)
关键改动说明
- 移除所有全局变量,将用户的游戏状态(分数、正确答案)存入
request.session,每个用户独立拥有自己的会话数据 - 分数改用整数存储,答对加1、答错重置为0,逻辑更简洁
- 用户提交猜测时,验证的是会话中保存的上一轮正确答案,而非易被覆盖的全局变量
- 每个请求独立生成上下文对象,避免不同请求之间的状态污染
注意事项
- Django默认已开启session功能(默认用数据库存储),无需额外配置即可使用
- 如果需要长期保存用户的历史分数,可以扩展User模型添加
score字段,session仅适合存储当前游戏的临时进度
内容的提问来源于stack exchange,提问作者bucko28
相关产品推荐
相关产品推荐

