Guest User

bob

a guest
Jul 11th, 2009
219
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. from django.forms import ModelForm
  2. from django.forms.models import BaseInlineFormSet
  3. from django import forms
  4. from django.forms.util import flatatt, ErrorDict, ErrorList, ValidationError
  5. from django.forms.formsets import DELETION_FIELD_NAME
  6.  
  7. class DeleteIfEmptyModelForm(ModelForm):
  8.     """
  9.    A ModelForm which marks itself valid and empty if all visible fields are
  10.    blank or all-whitespace.
  11.    """
  12.     def full_clean(self):
  13.         self._errors = ErrorDict()  #added
  14.         if not self.is_bound:
  15.             return
  16.         if not self.is_empty():
  17.             return super(DeleteIfEmptyModelForm, self).full_clean()
  18.  
  19.     def is_empty(self):
  20.         self.cleaned_data = {}
  21.         if not hasattr(self, '_empty'):
  22.             self._empty = True
  23.             for boundfield in self:
  24.                 field = self.fields[boundfield.name]
  25.                 value = field.widget.value_from_datadict(
  26.                     self.data, self.files, self.add_prefix(boundfield.name))
  27.                 if not boundfield.is_hidden and boundfield.name != DELETION_FIELD_NAME and value is not None and unicode(value).strip(): #changed
  28.                     self._empty = False
  29.                     break
  30.                 try:
  31.                     clean_value = field.clean(value)
  32.                 except ValidationError:
  33.                     clean_value = ''
  34.                 self.cleaned_data[boundfield.name] = clean_value
  35.         return self._empty
  36.  
  37. class DeleteIfEmptyInlineFormSet(BaseInlineFormSet):
  38.     """
  39.    Modified version of django.forms.models.BaseInlineFormSet for allowing
  40.    deleting objects by emptying their visible fields instead of checking the
  41.    delete checkbox.
  42.  
  43.    Not overriding _get_deleted_forms() since it doesn't seem to be used in my
  44.    use case.
  45.    """
  46.     def save_existing_objects(self, commit=True):
  47.         """Only one small change here, see comment below"""
  48.         self.changed_objects = []
  49.         self.deleted_objects = []
  50.         if not self.get_queryset():
  51.             return []
  52.         existing_objects = {}
  53.         for obj in self.get_queryset():
  54.             existing_objects[obj.pk] = obj
  55.         saved_instances = []
  56.         for form in self.initial_forms:
  57.             obj = existing_objects[form.cleaned_data[self._pk_field.name]]
  58.             # the change is on this line:
  59.             if self.can_delete and (form.cleaned_data[DELETION_FIELD_NAME] or form.is_empty()):
  60.                 self.deleted_objects.append(obj)
  61.                 obj.delete()
  62.             else:
  63.                 if form.changed_data:
  64.                     self.changed_objects.append((obj, form.changed_data))
  65.                     saved_instances.append(self.save_existing(form, obj, commit=commit))
  66.                     if not commit:
  67.                         self.saved_forms.append(form)
  68.         return saved_instances
  69.  
  70.     def add_fields(self, form, index):
  71.         """Override delete field and make it hidden."""
  72.         super(DeleteIfEmptyInlineFormSet, self).add_fields(form, index)
  73.         form.fields[DELETION_FIELD_NAME].widget = forms.HiddenInput()
RAW Paste Data