为什么我的 Django 表单执行了两次?
Why is My Django Form Executed Twice?
谁能给我解释一下为什么表格 2 执行了两次?换句话说,我会在控制台中看到 2 个打印语句 "Hello from form 2,"。
我从表格 1 单击 "Submit" 后出现第一个打印语句。第二个打印语句出现在我从表格 2 单击 "Submit" 之后。如何让它只打印一次?
views.py
def form1 (request):
NameFormSet = formset_factory (NameForm, formset = BaseNodeFormSet, extra = 2, max_num = 5)
if request.method == 'POST':
name_formset = NameFormSet (request.POST, prefix = 'nameform')
if name_formset.is_valid ():
data = name_formset.cleaned_data
request.session ['data'] = data
return HttpResponseRedirect ('form2')
else:
name_formset = NameFormSet (prefix = 'nameform')
context = {'name_formset': name_formset}
return render (request, 'nameform/form1.html', context)
def form2 (request):
data = request.session ['data']
print ('Hello from form 2') # <==== This statement printed twice in the console
CheckBoxFormSet = formset_factory (CheckBox, extra = 2, max_num = 5)
if request.method == 'POST':
checkbox_formset = CheckBoxFormSet (request.POST, prefix = 'checkbox')
if checkbox_formset.is_valid ():
for i, form in enumerate (checkbox_formset.cleaned_data):
data [i].update (form) # Join cleaned data with original data
del request.session ['data']
context = {'data': data}
return render (request, 'nameform/success.html', context)
checkbox_formset = CheckBoxFormSet (prefix = 'checkbox')
context = {'checkbox_formset': checkbox_formset, 'data': data}
return render (request, 'nameform/form2', context)
更新 1:
"print"语句实际上是一个后端方法,它处理从表单1获取的数据并显示在表单2中。离开现在的位置会导致该方法处理信息两次。我这样做没有问题或错误,但这是不必要的。
例如:
def form2 (request):
data = request.session ['data']
n, errors = getInfo (data) # <==== This statement performed twice in the console
if request.method = 'POST':
....
if checkbox_formset.is_valid ():
for i, form in enumerate (checkbox_formset.cleaned_data):
data [i].update (form) # Join cleaned data with original data
n.process_new_data (data, errors)
del request.session ['data']
context = {'data': data, 'errors': error}
return render (request, 'nameform/success.html', context)
else:
checkbox_formset = CheckBoxFormset (prefix = 'checkbox')
context = {'data': data, 'errors': error}
return render (request, 'nameform/form2.html', context)
更新 2:
由于我的解释有点长,请允许我在这里解决Ale问题。
是的,我完全理解为什么要处理两次。简要回答您的问题,将 getInfo 放入 'POST' 会给我一个上下文未绑定错误,因为第一个重定向中不存在上下文 "errors" 字典。
context = {'data': data, 'errors': errors}
我想更新我的 post 以便我可以解释为什么我不能使用你的方法。 GetInfo 从 form1 中获取数据,对其进行处理,然后将其传递给 form 2 以进行显示。我可以在 form1 中完成所有这些操作,但随后我将不得不在 form2 中重做,因为 form2 在不通过会话传递的情况下不知道 'n' 或 'errors' 是什么。我只是想看看是否有更好的方法来做到这一点。
form2 视图 运行 两次,一次是创建表单并呈现模板的 form1 的重定向,缺少 if request.method == 'POST'
部分,因为这次请求是 'GET'.
当您将 form2 提交回相同的视图方法时,它会再次打印您指示的行,这次 if 块中的代码执行,因为请求是 'POST'。
关键是重定向到 form2 视图的这一行:
return HttpResponseRedirect ('form2')
您可以通过将堆栈跟踪包含到您的打印语句中来调试它:
import traceback
print ''.join(traceback.format_stack())
谁能给我解释一下为什么表格 2 执行了两次?换句话说,我会在控制台中看到 2 个打印语句 "Hello from form 2,"。
我从表格 1 单击 "Submit" 后出现第一个打印语句。第二个打印语句出现在我从表格 2 单击 "Submit" 之后。如何让它只打印一次?
views.py
def form1 (request):
NameFormSet = formset_factory (NameForm, formset = BaseNodeFormSet, extra = 2, max_num = 5)
if request.method == 'POST':
name_formset = NameFormSet (request.POST, prefix = 'nameform')
if name_formset.is_valid ():
data = name_formset.cleaned_data
request.session ['data'] = data
return HttpResponseRedirect ('form2')
else:
name_formset = NameFormSet (prefix = 'nameform')
context = {'name_formset': name_formset}
return render (request, 'nameform/form1.html', context)
def form2 (request):
data = request.session ['data']
print ('Hello from form 2') # <==== This statement printed twice in the console
CheckBoxFormSet = formset_factory (CheckBox, extra = 2, max_num = 5)
if request.method == 'POST':
checkbox_formset = CheckBoxFormSet (request.POST, prefix = 'checkbox')
if checkbox_formset.is_valid ():
for i, form in enumerate (checkbox_formset.cleaned_data):
data [i].update (form) # Join cleaned data with original data
del request.session ['data']
context = {'data': data}
return render (request, 'nameform/success.html', context)
checkbox_formset = CheckBoxFormSet (prefix = 'checkbox')
context = {'checkbox_formset': checkbox_formset, 'data': data}
return render (request, 'nameform/form2', context)
更新 1: "print"语句实际上是一个后端方法,它处理从表单1获取的数据并显示在表单2中。离开现在的位置会导致该方法处理信息两次。我这样做没有问题或错误,但这是不必要的。
例如:
def form2 (request):
data = request.session ['data']
n, errors = getInfo (data) # <==== This statement performed twice in the console
if request.method = 'POST':
....
if checkbox_formset.is_valid ():
for i, form in enumerate (checkbox_formset.cleaned_data):
data [i].update (form) # Join cleaned data with original data
n.process_new_data (data, errors)
del request.session ['data']
context = {'data': data, 'errors': error}
return render (request, 'nameform/success.html', context)
else:
checkbox_formset = CheckBoxFormset (prefix = 'checkbox')
context = {'data': data, 'errors': error}
return render (request, 'nameform/form2.html', context)
更新 2: 由于我的解释有点长,请允许我在这里解决Ale问题。
是的,我完全理解为什么要处理两次。简要回答您的问题,将 getInfo 放入 'POST' 会给我一个上下文未绑定错误,因为第一个重定向中不存在上下文 "errors" 字典。
context = {'data': data, 'errors': errors}
我想更新我的 post 以便我可以解释为什么我不能使用你的方法。 GetInfo 从 form1 中获取数据,对其进行处理,然后将其传递给 form 2 以进行显示。我可以在 form1 中完成所有这些操作,但随后我将不得不在 form2 中重做,因为 form2 在不通过会话传递的情况下不知道 'n' 或 'errors' 是什么。我只是想看看是否有更好的方法来做到这一点。
form2 视图 运行 两次,一次是创建表单并呈现模板的 form1 的重定向,缺少 if request.method == 'POST'
部分,因为这次请求是 'GET'.
当您将 form2 提交回相同的视图方法时,它会再次打印您指示的行,这次 if 块中的代码执行,因为请求是 'POST'。
关键是重定向到 form2 视图的这一行:
return HttpResponseRedirect ('form2')
您可以通过将堆栈跟踪包含到您的打印语句中来调试它:
import traceback
print ''.join(traceback.format_stack())