【问题标题】:How to have multiple of the same form on the same page in django如何在 django 的同一页面上拥有多个相同的表单
【发布时间】:2020-04-22 08:06:43
【问题描述】:

我在我的网页上多次使用同一个表单。

这是我的观点.py

if request.method == "POST":
    form1 = TheForm(request.POST)
    form2 = TheForm(request.POST)
    form3 = TheForm(request.POST)

        if form1.is_valid() and form2.is_valid() and form3.is_valid():

这是我的模板页面:

<form method="POST">
{% csrf_token %}
{{form1.as_p}}
{{form2.as_p}}
{{form3.as_p}}
<button class="waves-effect waves-light btn"> Button </button> </form>

当我尝试这样做时,它只保存来自 form3 的值,而不是其他值。

谢谢

【问题讨论】:

  • is_valid() 之后会发生什么?查看表单集。
  • 我只是使用 clean_data 收集数据,然后将这些信息输入到我的模型中。
  • 运行form1.save()form2.save()form3.save()
  • 当我尝试它只保存 form3 3 次。
  • 数据是request.POST表单怎么知道?您可以为不同的表单提供不同的前缀,然后从那里开始,但 formset 是这里的用例。使用表单集。

标签: python django forms


【解决方案1】:

问题是由于这 3 个表单完全相同,尤其是它们在呈现的 HTML 代码中具有相同的字段名称。让我举例说明。

想象你的表单是:

class TheForm(forms.Form):
    the_field = forms.CharField(label="Field")

在渲染完你的模板之后,你会得到差不多这样的代码:

<form method="POST">
    <input type="hidden" name="csrftoken" value="some-token">
    <p>
        <label for="id_the_field">Field</label>
        <input type="text" name="the_field" id="id_the_field">
    </p>
    <p>
        <label for="id_the_field">Field</label>
        <input type="text" name="the_field" id="id_the_field">
    </p>
    <p>
        <label for="id_the_field">Field</label>
        <input type="text" name="the_field" id="id_the_field">
    </p>
    <button class="waves-effect waves-light btn"> Button </button>
</form>

如您所见,所有 3 个表单都有相同的字段,包括输入字段的名称。如果要提交此表单,则这些字段之间没有区别,因此 Django 端的所有 3 个表单都将收到相同的值(在您的情况下,它来自第 3 个表单,但在某些情况下可能会有所不同)。

要解决这个问题,您可以使用不同的前缀初始化每个表单,如下所示:

if request.method == "POST":
    form1 = TheForm(request.POST, prefix="form1")
    form2 = TheForm(request.POST, prefix="form2")
    form3 = TheForm(request.POST, prefix="form3")

    if form1.is_valid() and form2.is_valid() and form3.is_valid():
        form1.save()
        form2.save()
        form3.save()
        return HttpResponseRedirect(...)
    else:
        return render(....)
else:
    form1 = TheForm(prefix="form1")
    form2 = TheForm(prefix="form2")
    form3 = TheForm(prefix="form3")

现在,呈现的 HTML 将如下所示:

<form method="POST">
    <input type="hidden" name="csrftoken" value="some-token">
    <p>
        <label for="id_form1_the_field">Field</label>
        <input type="text" name="form1_the_field" id="id_form1_the_field">
    </p>
    <p>
        <label for="id_form2_the_field">Field</label>
        <input type="text" name="form2_the_field" id="id_form2_the_field">
    </p>
    <p>
        <label for="id_form2_the_field">Field</label>
        <input type="text" name="form3_the_field" id="id_form3_the_field">
    </p>
    <button class="waves-effect waves-light btn"> Button </button>
</form>

如您所见,现在字段具有不同的不同名称,因此当用户提交时,它们将由浏览器单独发送回您的 Django 后端。

您可以在Django docs 中找到有关表单前缀的更多信息

【讨论】:

    【解决方案2】:

    &lt;form&gt; 中有多次相同的东西应该可以工作as described here

    对于Django你需要使用formsets,看起来像你想要实现的

    【讨论】:

      【解决方案3】:

      我找到了一个解决方案,不确定它是否最有效。

      我只保留了所有内容,除了现在我在模板本身中打乱查询集。

      我使用此链接here 来执行随机播放,并使用此link 对模板标签进行故障排除。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多