【问题标题】:Override Django formset delete behavior: Delete form instance if empty field in Django model formset覆盖 Django 表单集删除行为:如果 Django 模型表单集中有空字段,则删除表单实例
【发布时间】:2013-06-22 15:40:03
【问题描述】:

我经常遇到这种情况:

我想隐藏formset中的默认删除框,如果在formset的每个表单中清除了某个字段,则删除对象的实例。

典型的问题是,验证会妨碍或破坏空白表单检测并在保存表单集时开始添加所有表单(甚至是空白额外)。

【问题讨论】:

    标签: django formset


    【解决方案1】:

    BaseFormSet 上有一个名为 _should_delete_form 的方法,它可以轻松根据您自己的标准自动删除实例,但它是一种“私有”方法,因此不确定未来的支持。您还需要通过调用formset.save() 来保存表单集。

    在下面的示例中,如果所有fields 值的计算结果为假值,它将删除一行。

    class MyFormSet(forms.BaseInlineFormSet):
        def _should_delete_form(self, form):
            """Return whether or not the form should be deleted."""
            if form.cleaned_data.get(forms.formsets.DELETION_FIELD_NAME):
                return True  # marked for delete
            fields = ('name', 'question', 'amount', 'measure', 'comment')
            if not any(form.cleaned_data[i] for i in fields):
                return True
            return False
    

    【讨论】:

      【解决方案2】:

      这是我找到的解决方案:

      此代码创建一个模型表单集,通过允许空白字段确保其验证,然后在保存时确定要删除哪些对象以及要保存哪些表单。

      TaskFormset = inlineformset_factory(User, FAQ, extra=3, can_delete=False, exclude=('user', 'answer',))
      formset = TaskFormset(request.POST, request.FILES, instance=user)
      for form in formset:
          form.fields['question'].required = False
      
      // later when performing the formset save
      
      for form in formset:
          if form.instance.pk and form.cleaned_data['question'].strip() == '':
              form.instance.delete()
          elif form.cleaned_data:
              form.save()
      

      【讨论】:

      • 你可以添加一些javascript,当字段为空时将删除标志设置为true。
      • 不,Kiran,他会想做那个处理服务器端。依靠javascript做到这一点,就等于接受了用户的判断。
      • 控制表单集中的表单似乎比添加外部 JS 代码更 Pythonic。这比添加 JS 和 CSS 开销更容易测试并且看起来更简单。谢谢你的建议。
      猜你喜欢
      • 2012-09-07
      • 1970-01-01
      • 2018-03-08
      • 1970-01-01
      • 1970-01-01
      • 2010-10-08
      • 1970-01-01
      • 2012-12-20
      • 1970-01-01
      相关资源
      最近更新 更多