【问题标题】:Multiple Django Forms in Single View: Why Does One POST Clear Other Forms?单一视图中的多个 Django 表单:为什么一个 POST 会清除其他表单?
【发布时间】:2020-04-30 19:14:26
【问题描述】:

我正在尝试在 Django 的同一页面上实现三个表单。每个表单都有自己的提交按钮,如我的代码所示。当我在任何一个表单上提交数据时,数据会被保存,但其他表单会在结果刷新时变为空白,例如,如果需要某个字段,我会在其他表单上收到验证错误。

我的预感是 Django 处理 POST 和后续页面刷新的方式是导致问题的原因,并且无论我按下哪个提交按钮,它都会尝试验证所有表单。我认为按所示映射按钮名称可以防止这种情况发生,但显然不能,也许我必须使用 AJAX 单独处理每个表单来解决这个问题。但是我不确定这是否是解决方法,如果有人能阐明真正发生的事情(即解释 Django 在提交时试图做什么),我会喜欢它,这样我就可以更好地理解如何解决。非常感谢任何帮助。在 Django 中在一个视图中处理多个表单绝非易事。

这是我的代码:

Views.py

def update_machine_view(request, brand_name_slug, mclass_slug, profile_slug):

    machineentry = MachineEntry.objects.prefetch_related().select_related().get(profile_slug=profile_slug)

    f_plate         = PlateForm(request.POST or None, instance=machineentry.plate)
    f_dimensions    = DimensionsForm(request.POST or None, instance=machineentry.dimensions)
    f_chassis       = ChassisForm(request.POST or None, instance=machineentry.chassis)

    if request.method == 'POST' and 'save_plate' in request.POST:
        if f_plate.is_valid():
            f_plate.save()

    if request.method == 'POST' and 'save_dimensions' in request.POST:
        if f_dimensions.is_valid():
            f_dimensions.save()

    if request.method == 'POST' and 'save_chassis' in request.POST:
        if f_chassis.is_valid():
            f_chassis.save()


    context = {
        'f_plate': f_plate,
        'f_dimensions': f_dimensions,
        'f_chassis': f_chassis,
        'obj': machineentry,
    }

    return render(request, "machines/update_machine_form.html", context)

模板:



<form method="post">
   {% csrf_token %}
   {{ f_plate | crispy }}
   <button type='submit' name='save_plate'>Save</button>
</form>
<form method="post">
   {% csrf_token %}
   {{ f_dimensions | crispy }}
   <button type='submit' name='save_dimensions'>Save</button>
</form>
<form method="post">
   {% csrf_token %}
   {{ f_chassis | crispy }}
   <button type='submit' name='save_chassis'>Save</button>
</form>

【问题讨论】:

  • 我可以确认,在不使用 AJAX 的情况下,我没有遇到任何“正确”的解决方案,可以在一个页面上提交多个表单。

标签: django django-forms


【解决方案1】:

我能理解的是,您在每个表单中都传递了request.POST,即使是未提交的表单也是如此。但是在request.POST 中,您拥有提交的表单的值,而不是其他表单的值。因此错误显示字段是必需的。我建议你这样做:

def update_machine_view(request, brand_name_slug, mclass_slug, profile_slug):

    machineentry = MachineEntry.objects.select_related('plate', 'dimensions', 'chassis').get(profile_slug=profile_slug)

    f_plate         = PlateForm(instance=machineentry.plate)
    f_dimensions    = DimensionsForm(instance=machineentry.dimensions)
    f_chassis       = ChassisForm(instance=machineentry.chassis)

    if request.method == 'POST':
        if 'save_plate' in request.POST:
             f_plate = PlateForm(request.POST, instance=machineentry.plate)
             if f_plate.is_valid():
                 f_plate.save()

        if 'save_dimensions' in request.POST:
            f_dimensions = DimensionsForm(request.POST, instance=machineentry.dimensions)
            if f_dimensions.is_valid():
               f_dimensions.save()

        if 'save_chassis' in request.POST:
             f_chassis = ChassisForm(request.POST, instance=machineentry.chassis)
             if f_chassis.is_valid():
                  f_chassis.save()


    context = {
        'f_plate': f_plate,
        'f_dimensions': f_dimensions,
        'f_chassis': f_chassis,
        'obj': machineentry,
    }

    return render(request, "machines/update_machine_form.html", context)

【讨论】:

  • 感谢您提供这个出色的解决方案,您真的帮助了我!我也很欣赏以上 devbob 的观点,谢谢!我想我要对这些表单进行 ajaxify 处理,但现在我知道如何处理处于当前状态的帖子了。
猜你喜欢
  • 2017-02-26
  • 2016-03-22
  • 2020-05-31
  • 1970-01-01
  • 2018-01-27
  • 2013-04-19
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
相关资源
最近更新 更多