Opened 5 years ago

Last modified 8 months ago

#12697 new New feature

Prevent deletion of some rows in a formset

Reported by: shadfc Owned by: nobody
Component: Forms Version: 1.1
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Original post to dev mailing list: http://groups.google.com/group/django-developers/browse_frm/thread/5008b34e29c80417

I need to prevent deletion of some of the rows on an inline modelformset.

At first I thought I could just do some validation in clean() and
attach errors to the "DELETE" (really the field mapped to
forms.formsets.DELETION_FIELD_NAME), but
is_valid()
on the formset ignores errors on forms when can_delete is True.

A few possible solutions:

  1. Modify formset validation to ignore errors on the forms EXCEPT on the field referenced by forms.formsets.DELETION_FIELD_NAME ("DELETE" normally).
  1. Make the behavior of ignoring validation errors when can_delete is True explicit. Add a parameter such as "ignore_validation_on_delete" which defaults to True for backward compatibility. When False, formset validation fails on any errors.
  1. Allow can_delete to be specified per form in a formset, perhaps in a way similar to initial -- an iterable of boolean values.
  1. Add a pre-delete hook on model forms which can be used to circumvent deletion.

Change History (5)

comment:1 Changed 5 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

comment:2 Changed 4 years ago by mattmcc

  • Severity set to Normal
  • Type set to New feature

comment:3 Changed 3 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:4 Changed 3 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

comment:5 Changed 8 months ago by darklow

I found a very easy solution for this problem to avoid unwanted deletion of some inlines
You can just override delete_forms property method.

class MyInlineFormSet(BaseInlineFormSet):

    @property
    def deleted_forms(self):
        deleted_forms = super(MyInlineFormSet, self).deleted_forms

        for i, form in enumerate(deleted_forms):
            if some_criteria_to_prevent_deletion:
                deleted_forms.pop(i)

        return deleted_forms
Note: See TracTickets for help on using tickets.
Back to Top