如何在Flask中无需新增@app.route实现会话重置?
问题描述
课堂任务要求制作一个赚取金币的简易Flask游戏页面,限制最多使用2个@app.route。附加任务是添加重置按钮重新开始游戏,但现有路由无法实现该功能。尝试将按钮方法改为get并为主路由添加GET方法后仍未达到预期效果,附上代码寻求实现建议。
原Python代码
@app.route('/') def index(): if 'gold' not in session: session['gold'] = 0 session['earnings'] = [] session['losses'] = [] if request.method == 'GET': session.clear print(session['gold'], "in the bank") return render_template('index.html') @app.route('/process_money', methods=['POST']) def process_money(): print(request.form) if request.form['get_gold'] == 'rice_paddy': temp = random.randint(10,20) session['gold'] += temp earning = session['earnings'] earning.append(f"Your hard work paid off, you earned {temp} gold from the rice paddy!") session['earnings'] = earning print(f"Your hard work paid off, you earned {temp} gold from the rice paddy!") if request.form['get_gold'] == 'hideout': temp = random.randint(5,10) session['gold'] += temp earning = session['earnings'] earning.append(f"After rummaging around in the cushions, you found {temp} gold in the hideout!") session['earnings'] = earning print(f"After rummaging around in the cushions, you found {temp} gold in the hideout!") if request.form['get_gold'] == 'castle': temp = random.randint(2,5) session['gold'] += temp earning = session['earnings'] earning.append(f"While no one was looking, you stole {temp} gold from the castle!") session['earnings'] = earning print(f"While no one was looking, you stole {temp} gold from the castle!") if request.form['get_gold'] == 'dice_den': temp = random.randint(-50,50) if temp >= 0: session['gold'] += temp earning = session['earnings'] earning.append(f"Nice! You gained {temp} gold while gambling at the dice den!") session['earnings'] = earning print(f"Nice! You gained {temp} gold while gambling at the dice den!") elif temp <= 0: session['gold'] += temp losses = session['losses'] losses.append(f"Aww, too bad! You lost {temp} gold while gambling at the dice den!") session['losses'] = losses print(f"Aww, too bad! You lost {temp} gold while gambling at the dice den!") return redirect('/') if __name__ == "__main__": app.run(debug=True)
原HTML代码
<body> <div id="main" class="container bg-dark"> <label for="your_gold" class="text-light" style="margin-top: 1.5rem;">Your Gold:</label> <input type="number" value="{{session['gold']}}"> <div class="d-flex"> <div class="container"> <form method="post" action="/process_money"> <input type="hidden" name="get_gold" value="rice_paddy"> <h4>Rice Paddy</h4> <p>(earns 10-20 gold)</p> <input type="submit" name="rice_paddy" id="rice_paddy" value="Earn Gold!"> </form> </div> <div class="container"> <form method="post" action="/process_money"> <input type="hidden" name="get_gold" value="hideout"> <h4>Hideout</h4> <p>(earns 5-10 gold)</p> <input type="submit" name="hideout" id="hideout" value="Find Gold!"> </form> </div> <div class="container"> <form method="post" action="/process_money"> <input type="hidden" name="get_gold" value="castle"> <h4>Shiro</h4> <p>(earns 2-5 gold)</p> <input type="submit" name="castle" id="castle" value="Steal Gold!"> </form> </div> <div class="container"> <form method="post" action="/process_money"> <input type="hidden" name="get_gold" value="dice_den"> <h4>Dice Den</h4> <p>(earns/takes 0-50 gold)</p> <input type="submit" name=dice_den id=dice_den value="Gamble Gold!"> </form> </div> </div> <h5 class="text-light">Activities:</h5> <div id="activities" class="container"> <ul> {% for earning in session['earnings'] %} <li class="text-success">{{earning}}</li> {% endfor %} {% for loss in session['losses'] %} <li class="text-danger">{{loss}}</li> {% endfor %} </ul> </div> <a method='get' class="btn btn-danger" style="border: 2px solid black; width: auto; margin-bottom: 20px;" href="/">Reset</a> </div> </body> </html>
解决方案
问题分析
session.clear是方法调用,缺少括号,正确写法是session.clear(),否则不会执行清除操作。- 原主路由中每次GET请求都清除session,导致用户正常访问页面时也会重置游戏,逻辑错误。
- HTML中的
<a>标签的method属性无效,GET请求无法通过该属性控制,需要通过查询参数区分重置请求。
修改步骤
- 调整主路由逻辑:添加查询参数
reset,仅当request.args.get('reset')存在时清除session,之后重新初始化游戏数据。 - 修正session调用:将
session.clear改为session.clear()。 - 修改重置按钮链接:将链接改为
/?reset=true,触发重置逻辑。
修改后的Python代码
from flask import Flask, render_template, request, redirect, session import random app = Flask(__name__) app.secret_key = 'your_secret_key_here' # 必须设置密钥,session才能正常工作 @app.route('/') def index(): # 处理重置请求 if request.args.get('reset'): session.clear() # 初始化session数据(如果不存在) if 'gold' not in session: session['gold'] = 0 session['earnings'] = [] session['losses'] = [] print(session['gold'], "in the bank") return render_template('index.html') @app.route('/process_money', methods=['POST']) def process_money(): print(request.form) if request.form['get_gold'] == 'rice_paddy': temp = random.randint(10,20) session['gold'] += temp earning = session['earnings'] earning.append(f"你的努力有回报了!从稻田赚了{temp}金币!") session['earnings'] = earning elif request.form['get_gold'] == 'hideout': temp = random.randint(5,10) session['gold'] += temp earning = session['earnings'] earning.append(f"翻遍垫子后,你在藏身处找到了{temp}金币!") session['earnings'] = earning elif request.form['get_gold'] == 'castle': temp = random.randint(2,5) session['gold'] += temp earning = session['earnings'] earning.append(f"趁没人注意,你从城堡偷了{temp}金币!") session['earnings'] = earning elif request.form['get_gold'] == 'dice_den': temp = random.randint(-50,50) if temp >= 0: session['gold'] += temp earning = session['earnings'] earning.append(f"不错!在骰子馆赌博赢了{temp}金币!") session['earnings'] = earning else: session['gold'] += temp losses = session['losses'] losses.append(f"哎呀太糟了!在骰子馆赌博输了{abs(temp)}金币!") session['losses'] = losses return redirect('/') if __name__ == "__main__": app.run(debug=True)
修改后的HTML代码
<body> <div id="main" class="container bg-dark"> <label for="your_gold" class="text-light" style="margin-top: 1.5rem;">你的金币:</label> <input type="number" value="{{session['gold']}}" readonly> <!-- 设为只读防止手动修改 --> <div class="d-flex"> <div class="container"> <form method="post" action="/process_money"> <input type="hidden" name="get_gold" value="rice_paddy"> <h4>稻田</h4> <p>(赚取10-20金币)</p> <input type="submit" name="rice_paddy" id="rice_paddy" value="赚取金币!"> </form> </div> <div class="container"> <form method="post" action="/process_money"> <input type="hidden" name="get_gold" value="hideout"> <h4>藏身处</h4> <p>(赚取5-10金币)</p> <input type="submit" name="hideout" id="hideout" value="寻找金币!"> </form> </div> <div class="container"> <form method="post" action="/process_money"> <input type="hidden" name="get_gold" value="castle"> <h4>城堡</h4> <p>(赚取2-5金币)</p> <input type="submit" name="castle" id="castle" value="偷取金币!"> </form> </div> <div class="container"> <form method="post" action="/process_money"> <input type="hidden" name="get_gold" value="dice_den"> <h4>骰子馆</h4> <p>(赢取/损失0-50金币)</p> <input type="submit" name=dice_den id=dice_den value="赌博金币!"> </form> </div> </div> <h5 class="text-light">活动记录:</h5> <div id="activities" class="container" style="height: 200px; overflow-y: auto; background-color: white; padding: 10px;"> <ul> {% for earning in session['earnings'] %} <li class="text-success">{{earning}}</li> {% endfor %} {% for loss in session['losses'] %} <li class="text-danger">{{loss}}</li> {% endfor %} </ul> </div> <a class="btn btn-danger" style="border: 2px solid black; width: auto; margin-bottom: 20px; margin-top: 10px;" href="/?reset=true">重置游戏</a> </div> </body> </html>
额外优化说明
- 添加了
app.secret_key,Flask的session必须设置密钥才能正常使用。 - 将金币输入框设为
readonly,防止用户手动修改金币数值。 - 给活动记录框添加了滚动条和背景色,提升可读性。
- 将英文文本翻译成中文,更符合使用习惯。
内容的提问来源于stack exchange,提问作者Brad
相关产品推荐
相关产品推荐

