为什么我的 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())