【问题标题】:Django formset if TOTAL_FORMS has different number than actual number of forms如果 TOTAL_FORMS 的数字与实际表单数不同,则为 Django formset
【发布时间】:2013-05-04 09:24:50
【问题描述】:

在处理动态表单集时,有时 TOTAL_FORMS 大于实际表单数。此外,用户可以轻松修改此输入 TOTAL_FORMS。
例如,我的输入是

<input name='user-TOTAL_FORMS' type='hidden' value='5'/>

但是,只显示了 2 个实际表单。

在这种情况下,Django 在 formset.forms 变量中生成不需要的空表单。如果存在任何验证错误并且再次显示表单,这会产生问题。页面显示那些不需要的表格。 (在示例中,应仅显示 2 个实际表单,但由于总数为 5,因此用户总共看到 5 个表单)

如何删除这些不需要的表单、更新我的总数并使用更新的表单集重新显示表单?

编辑: 具有挑战性的部分是在删除表单时更新索引。所以表格总数与最后一个表格索引匹配。

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

    大声笑,这仍然是老问题,但真正的答案是“添加extra=0 属性,因为默认extra 定义为3”

    LinkFormSet = inlineformset_factory(
        ParentModel, 
        ChildModel,  
        fields = ('price', 'deadline',), 
        extra=0
    )
    

    更多文档可在此处获得:https://docs.djangoproject.com/en/2.1/ref/forms/models/#django.forms.models.inlineformset_factory

    【讨论】:

      【解决方案2】:

      这是一个老问题,我不确定 Django 自那以后是否发生了很大变化。但我最终这样做的方式是编写一个函数来更新表单集数据。这里的关键是首先制作表单集数据(QueryDict)的副本。这是代码:

      def updateFormDataPrefixes(formset):
          """
          Update the data of the formset to fix the indices. This will assign
          indices to start from 0 to the length. To do this requires copying 
          the existing data and update the keys of the QueryDict. 
          """
      
          # Copy the current data first
          data = formset.data.copy()
      
          i = 0
          nums = []
          for form in formset.forms:
              num = form.prefix.split('-')[-1]
              nums.append(num)
              # Find the keys for this form
              matched_keys = [key for key in data if key.startswith(form.prefix)]
              for key in matched_keys:
                  new_key = key.replace(num, '%d'%i)
                  # If same key just move to the next form
                  if new_key == key:
                      break
                  # Update the form key with the proper index
                  data[new_key] = data[key]
                  # Remove data with old key
                  del data[key]
              # Update form data with the new key for this form
              form.data = data
              form.prefix = form.prefix.replace(num, '%d'%i)
              i += 1
      
          total_forms_key = formset.add_prefix(TOTAL_FORM_COUNT)
          data[total_forms_key] = len(formset.forms)
          formset.data = data
      

      【讨论】:

        猜你喜欢
        • 2022-11-05
        • 2015-12-28
        • 2021-10-28
        • 1970-01-01
        • 2012-11-02
        • 1970-01-01
        • 2019-07-15
        • 2018-12-24
        • 2018-03-30
        相关资源
        最近更新 更多