【问题标题】:Why is My Django Form Executed Twice?为什么我的 Django 表单执行了两次?
【发布时间】:2015-07-18 11:49:25
【问题描述】:

有人可以向我解释为什么表格 2 执行了两次吗?换句话说,我会在控制台中看到 2 个打印语句“Hello from form 2”。

第一个打印语句出现在我从表单 1 中单击“提交”之后。第二个打印语句出现在我从表单 2 中单击的第二个“提交”之后。如何使它只打印一次?

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: “打印”语句实际上是一个后端方法,它处理从表格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”中会给我一个上下文,未绑定的错误,因为第一个重定向中不存在上下文“错误”字典。

context = {'data': data, 'errors': errors}

我会更新我的帖子,以便解释为什么我不能使用你的方法。 GetInfo 从 form1 获取数据,对其进行处理,然后将其传递给 form 2 以显示。我可以在 form1 中完成所有这些操作,但随后我将不得不在 form2 中重做它,因为如果不通过会话,form2 将不知道“n”或“错误”是什么。我只是想看看是否有更好的方法来做到这一点。

【问题讨论】:

  • 第一次打印发生在重定向上,当您执行 POST 时实际上有一个到 form2 的 GET 时。如果你把 pirnt 放在 if 请求之后……那么你只会得到一次。
  • 是的,这适用于打印声明,感谢您解决我的问题。真正的问题是“打印”语句是显示处理后的“数据”的实际后端程序。如果我将它移动到“if request”语句中,那么表单 2 将不受上下文语句的限制。我更新了表格 2 来说明我的意思。
  • 我认为你需要改写你的问题,@Ale 已经解决了这个问题:“有人可以向我解释为什么表格 2 执行了两次吗?换句话说,我会看到 2 个打印语句,”来自表格 2 的您好,”在控制台中。”
  • 对不起,你们很快。我刚刚编辑了原始帖子以使其更清晰。
  • @dreamzboy 正如我所说,出于同样的原因,它将被执行两次。首先获取表单,表单中的 POST 数据,因为您在 form1 中进行了重定向。你想什么时候使用getInfo?为什么需要执行一次?如果您只想在 post 上获取信息,请在检查表单是否有效后使用它。

标签: python django forms formset


【解决方案1】:

form2 视图运行两次,一次作为来自 form1 的重定向,它创建表单并呈现模板,缺少 if request.method == 'POST' 部分,因为这次请求是“GET”。

当您将 form2 提交回相同的视图方法时,它会再次打印您指定的行,这一次 if 块中的代码将执行,因为请求是“POST”。

关键是重定向到form2视图的这一行:

return HttpResponseRedirect ('form2')

【讨论】:

    【解决方案2】:

    您可以通过在打印语句中包含堆栈跟踪来调试它:

    import traceback
    print ''.join(traceback.format_stack())
    

    【讨论】:

    • 很高兴知道。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 2011-06-16
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    相关资源
    最近更新 更多