Advertisement
Guest User

bob

a guest
Jul 11th, 2009
543
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.05 KB | None | 0 0
  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()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement