Django单页提交两个表单时如何在第二个表单中使用第一个表单的数据
问题根源
HTTP协议本身是无状态的,你第一次提交GET表单生成对阵表后,stat变量只是当前请求的局部变量,第二次提交POST保存表单时是全新的请求,之前的stat和bracket数据自然不存在。另外原代码还存在变量作用域问题:GET分支里定义的stat1~stat5、bracket变量,在POST请求分支里没有提前初始化,访问必然为空。
修复方案
直接在第二个表单中添加隐藏域,把第一次提交的统计指标、生成的对阵表数据随保存请求一起提交即可,不需要额外引入session等复杂方案:
第一步:修改HTML模板
<form method="GET"> {% csrf_token %} <label for="stat1">Most Important Stat:</label> <select name="stat1" id="stat1"> <option value="Stat 1">Stat 1</option> <option value="Stat 2">Stat 2</option> <option value="Stat 3">Stat 3</option> <option value="Stat 4">Stat 4</option> <option value="Stat 5">stat 5</option> </select> <label for="stat2">Second Most Important Stat:</label> <select name="stat2" id="stat2"> <option value="Stat 1">Stat 1</option> <option value="Stat 2">Stat 2</option> <option value="Stat 3">Stat 3</option> <option value="Stat 4">Stat 4</option> <option value="Stat 5">stat 5</option> </select> <label for="stat3">Third Most Important Stat:</label> <select name="stat3" id="stat3"> <option value="Stat 1">Stat 1</option> <option value="Stat 2">Stat 2</option> <option value="Stat 3">Stat 3</option> <option value="Stat 4">Stat 4</option> <option value="Stat 5">stat 5</option> </select> <label for="stat4">Fourth Most Important Stat:</label> <select name="stat4" id="stat4"> <option value="Stat 1">Stat 1</option> <option value="Stat 2">Stat 2</option> <option value="Stat 3">Stat 3</option> <option value="Stat 4">Stat 4</option> <option value="Stat 5">stat 5</option> </select> <label for="stat5">Fifth Most Important Stat:</label> <select name="stat5" id="stat5"> <option value="Stat 1">Stat 1</option> <option value="Stat 2">Stat 2</option> <option value="Stat 3">Stat 3</option> <option value="Stat 4">Stat 4</option> <option value="Stat 5">stat 5</option> </select> <!-- 去掉无效的onclick事件,普通表单提交即可 --> <button type="submit">Submit</button> </form> <form method="post"> {% csrf_token %} <!-- 新增隐藏域,同步统计指标和对阵表数据 --> <input type="hidden" name="stat1" value="{{ request.GET.stat1 }}"> <input type="hidden" name="stat2" value="{{ request.GET.stat2 }}"> <input type="hidden" name="stat3" value="{{ request.GET.stat3 }}"> <input type="hidden" name="stat4" value="{{ request.GET.stat4 }}"> <input type="hidden" name="stat5" value="{{ request.GET.stat5 }}"> <input type="hidden" name="bracket" value="{{ bracket|join:',' }}"> <div class="txt_field"> <input id="name" type="text" name="name" required> <label>Bracket Name</label> </div> <input type="Submit" value="Save Bracket"> </form>
第二步:修改views.py逻辑
def createBracket(request, user_id): user = get_object_or_404(User, pk=user_id) # 提前初始化变量,避免作用域报错 bracket = [] stat1 = stat2 = stat3 = stat4 = stat5 = None # 生成对阵表逻辑 if request.method == 'GET' and 'stat1' in request.GET: stat1 = request.GET.get('stat1') stat2 = request.GET.get('stat2') stat3 = request.GET.get('stat3') stat4 = request.GET.get('stat4') stat5 = request.GET.get('stat5') ordered_stats = [stat1, stat2, stat3, stat4, stat5] # 调用生成对阵表的函数 bracket = ["Virginia-Tech", "Colgate", "Arkansas", "Florida", "Drexel", "Illinois", "Utah St", "Texas Tech"] # 保存对阵表逻辑 if request.method == 'POST' and 'name' in request.POST: save_form = SaveForm(request.POST) if save_form.is_valid(): # 直接从POST请求取数据,不需要复用之前请求的变量 stat1 = request.POST.get('stat1') stat2 = request.POST.get('stat2') stat3 = request.POST.get('stat3') stat4 = request.POST.get('stat4') stat5 = request.POST.get('stat5') bracket = request.POST.get('bracket', '').split(',') Bracket.objects.create( bracket_name=save_form.cleaned_data['name'], user=user, bracket=bracket, stat1=stat1, stat2=stat2, stat3=stat3, stat4=stat4, stat5=stat5, ) # 保存成功后直接跳转,避免重复提交 return redirect('你的成功页面路由名', user_id=user_id) else: save_form = SaveForm() context = {'user': user, 'user_id': user_id, 'bracket': bracket, 'save_form': save_form} return render(request, 'project/createBracket.html', context)
内容的提问来源于stack exchange,提问作者Sophia
相关产品推荐
相关产品推荐

