Here is what I came up with. I had to override ModelForm as well to get rid of validation errors in emptied forms. This solution works in my use case where I only have CharFields and IntegerFields. It's not as simple as I had wished. Can it be?
class DeleteIfEmptyModelForm(ModelForm): """ A ModelForm which marks itself valid and empty if all visible fields are blank or all-whitespace. """ def full_clean(self): if not self.is_bound: return if not self.is_empty(): return super(DeleteIfEmptyModelForm, self).full_clean() def is_empty(self): self.cleaned_data = {} if not hasattr(self, '_empty'): self._empty = True for boundfield in self: field = self.fields[boundfield.name] value = field.widget.value_from_datadict( self.data, self.files, self.add_prefix (boundfield.name)) if not boundfield.is_hidden and boundfield.name != DELETION_FIELD_NAME and value is not None and str(value).strip(): self._empty = False break try: clean_value = field.clean(value) except ValidationError: clean_value = '' self.cleaned_data[boundfield.name] = clean_value return self._empty class DeleteIfEmptyInlineFormSet(BaseInlineFormSet): """ Modified version of django.forms.models.BaseInlineFormSet for allowing deleting objects by emptying their visible fields instead of checking the delete checkbox. Not overriding _get_deleted_forms() since it doesn't seem to be used in my use case. """ def save_existing_objects(self, commit=True): """Only one small change here, see comment below""" self.changed_objects = [] self.deleted_objects = [] if not self.get_queryset(): return [] existing_objects = {} for obj in self.get_queryset(): existing_objects[obj.pk] = obj saved_instances = [] for form in self.initial_forms: obj = existing_objects[form.cleaned_data [self._pk_field.name]] # the change is on this line: if self.can_delete and (form.cleaned_data [DELETION_FIELD_NAME] or form.is_empty()): self.deleted_objects.append(obj) obj.delete() else: if form.changed_data: self.changed_objects.append((obj, form.changed_data)) saved_instances.append(self.save_existing(form, obj, commit=commit)) if not commit: self.saved_forms.append(form) return saved_instances def add_fields(self, form, index): """Override delete field and make it hidden.""" super(DeleteIfEmptyInlineFormSet, self).add_fields(form, index) form.fields[DELETION_FIELD_NAME].widget = forms.HiddenInput() # usage: formset_class = forms.models.inlineformset_factory( parent_model, model, form=DeleteIfEmptyModelForm, formset=DeleteIfEmptyInlineFormSet) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---