带有两个提交按钮的 Django 表单。 . .一个需要字段,一个不需要

Posted

技术标签:

【中文标题】带有两个提交按钮的 Django 表单。 . .一个需要字段,一个不需要【英文标题】:Django form with two submit buttons . . . one requires fields and one doesn't 【发布时间】:2016-06-10 13:05:15 【问题描述】:

我认为这应该是一个相当简单的问题。 . .我有一个带有两个不同提交按钮的 Django 表单。第一个提交按钮仅用于将输入到表单字段中的任何值保存到数据库(因此用户可以稍后返回并完成表单)。我希望单击第一个提交按钮时不需要表单字段。但是,当用户单击第二个提交按钮时,所有字段都应该是必需的。有没有办法做到这一点?还是我只需为每个提交按钮复制一次表单?

【问题讨论】:

【参考方案1】:

上面的答案有效,但我更喜欢这种方式:Changing required field in form based on condition in views (Django)

我有两个按钮:

<!-- simply saves the values - all fields aren't required unless the user is posting the venue -->
<input type="submit" name="mainForm" value="Save">

<!-- post the values and save them to the database - fields ARE required-->
<input type="submit" name="postVenue" value="Post Venue">

我默认将所有表单字段设为required=False,然后在我的视图中显示:

if 'postVenue' in request.POST:
    form = NewVenueForm(request.POST)
    form.fields['title'].required = True
    form.fields['category'].required = True
    # do this for every form field

elif 'mainForm' in request.POST:     
    form = NewVenueForm(request.POST)

谢谢大家!!

【讨论】:

【参考方案2】:

如果您为提交按钮手动编写 html,您可以添加一个 namevalue 属性,您的 Django 应用可以使用该属性:

<button name="action" value="save">Save</button>
<button name="action" value="submit">Submit</button>

提交表单后,您将能够知道用户打算执行的操作。

class MyForm(forms.Form):

    def __init__(self, data=None, *args, **kwargs):
        super(MyForm, self).__init__(data=data, *args, **kwargs)

        # store user's intended action in self.action
        self.action = data.get('action') if data else None

        # set form fields to be not required if user is trying to "save"
        if self.action == 'save':
            for field in self.fields:
                field.required = False

【讨论】:

谢谢!但是我对表单的 init 函数不是很熟悉,当我使用此代码时,我在“self.action = data.get”行上收到一条错误消息“name 'data' is not defined” ('action') if data else None" ?? 您需要在__init__ 方法签名中添加data=None @laurenll 这个答案有帮助吗?如果您有任何问题或澄清,请告诉我,我很乐意更新答案 是的,这绝对是有帮助的@derekkwok!太感谢了!但我最终选择了不同的解决方案。见下文。 我认为data.get('action', None)data.get('action') if data else None 更pythonic【参考方案3】:

这在技术上不应该使用“必需”字段属性,因为 Django 字段在表单初始化时设置为可选/必需。

我们看一下django调用栈:

    Views.py 接收 GET 请求并使用您的 Forms.py 表单类初始化表单。 此时,您的所有字段都使用它们的“必需”属性创建。 当您单击一个按钮时,Views.py 会收到一个 POST 请求。 更改字段的“必填”属性为时已晚,因为它们在 GET 请求初始化表单时已设置 (POST 请求返回重定向或新表单)

如果您确实尝试更改 POST 请求中的“必需”属性并且该字段为空,您的表单将无效(当您调用 @987654325 时也称为@ 它会返回 False)。

警告:那么唯一可能的解决方法是检查您的 POST 请求中的字段并使用 Django message 但不建议这样做,因为它会破坏 Django 架构,迫使您重新加载您的表单(而不是重定向)并丢失用户提交的数据。

更新:

可以在 jquery 中通过使用隐藏的提交按钮和常规的可见按钮来执行此操作。常规按钮 onClick 调用 jquery 设置您想要的任何字段,然后触发隐藏的提交按钮。

<head>
  <meta charset="utf-8" />
  <script data-require="jquery" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
  <script>
    const allFields = [''] //put all your field ids here

    $("#tableAdd").click(function () 

      // Set all your fields back to optional
      allFields.forEach(function(field) 
          $( "#" + field ).removeAttr('required');
      );

      // Set specific fields as required, 'manufacturer_date' being the field 'table_add' requires
      var requiredFields = ['manufacturer_date'];
      requiredFields.forEach(function(field) 
          $( "#" + field ).attr('required', '');
      );

      // Then trigger the hidden input field to submit the form and send the POST request
      $( "#table_add" ).trigger( "click" );

    );
  </script>
</head>

<body>
  <input id="manufacturer_date" type="date">
  <input type="button" id="tableAdd" value="Add">
  <input type="submit" name="table_add" id="table_add" hidden>
</body>

【讨论】:

感谢您的回答!我很惊讶看到我 2 年前发布的帖子的更新! :)

以上是关于带有两个提交按钮的 Django 表单。 . .一个需要字段,一个不需要的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有 html 的 Django 表单制作提交按钮

带有单独提交和上传按钮的 Django 应用程序

确定在 Django 表单提交中单击了哪个提交按钮

Django为表单中的两个提交按钮呈现不同的模板

带有两个提交按钮和两个“目标”属性的 HTML 表单

Django:从其他表单传递参数以提交按钮