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

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

【问题讨论】:

    标签: python django django-forms django-templates


    【解决方案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调用栈:

      1. Views.py 接收 GET 请求并使用您的 Forms.py 表单类初始化表单。
      2. 此时,您的所有字段都使用它们的“必需”属性创建。
      3. 当您单击一个按钮时,Views.py 会收到一个 POST 请求。 更改字段的“必填”属性为时已晚,因为它们在 GET 请求初始化表单时已设置
      4. (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 年前发布的帖子的更新! :)
      猜你喜欢
      • 2016-10-27
      • 1970-01-01
      • 2012-03-12
      • 2022-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-14
      • 1970-01-01
      相关资源
      最近更新 更多