Ticket #6033: is_empty_clean_field.4.diff

File is_empty_clean_field.4.diff, 5.7 KB (added by Øyvind Saltvik <oyvind@…>, 16 years ago)

This one actually works

  • django/newforms/formsets.py

     
    116116        self.deleted_data = []
    117117        # Process change forms
    118118        for form in self.change_forms:
    119             if form.is_valid():
     119            if form.is_bound:
     120                form.full_clean(keep_invalid=True)
     121            if hasattr(form, 'cleaned_data'):
    120122                if self.deletable and form.cleaned_data[DELETION_FIELD_NAME]:
    121123                    self.deleted_data.append(form.cleaned_data)
     124                elif form.is_valid():
     125                    self.cleaned_data.append(form.cleaned_data)
    122126                else:
    123                     self.cleaned_data.append(form.cleaned_data)
     127                    self._is_valid = False
     128                    errors.append(form.errors)
    124129            else:
    125                 self._is_valid = False
    126             errors.append(form.errors)
     130                self._is_valid = False       
     131                errors.append(form.errors)
    127132        # Process add forms in reverse so we can easily tell when the remaining
    128133        # ones should be required.
    129134        reamining_forms_required = False
     
    168173        """
    169174        return self.cleaned_data
    170175
     176    def clean_field(self, form, f):
     177        if f in form.fields:
     178            field = form.fields.get(f)
     179            value = field.widget.value_from_datadict(self.data, self.files, '%s-%s' % (form.prefix, f))
     180            try:
     181                value = field.clean(value)
     182                if hasattr(self, 'clean_%s' % f):
     183                    value = getattr(self, 'clean_%s' % f)()
     184            except ValidationError, e:
     185                return False
     186            return value
     187        else:
     188            return False
     189               
    171190    def add_fields(self, form, index):
    172191        """A hook for adding extra fields on to each form instance."""
    173192        if self.orderable:
  • django/newforms/models.py

     
    310310            existing_objects[obj._get_pk_val()] = obj
    311311        saved_instances = []
    312312        for form in self.change_forms:
    313             obj = existing_objects[form.cleaned_data[self.model._meta.pk.attname]]
    314             if self.deletable and form.cleaned_data[DELETION_FIELD_NAME]:
     313            obj = existing_objects[self.clean_field(form, self.model._meta.pk.attname)]
     314            if self.deletable and self.clean_field(form, DELETION_FIELD_NAME):
    315315                obj.delete()
    316             else:
     316            elif self.is_valid():
    317317                saved_instances.append(self.save_instance(form, obj, commit=commit))
    318318        return saved_instances
    319319
     
    325325            # If someone has marked an add form for deletion, don't save the
    326326            # object. At some point it would be nice if we didn't display
    327327            # the deletion widget for add forms.
    328             if self.deletable and form.cleaned_data[DELETION_FIELD_NAME]:
     328            if self.deletable and self.clean_field(form, DELETION_FIELD_NAME):
    329329                continue
    330             new_objects.append(self.save_new(form, commit=commit))
     330            if self.is_valid():
     331                new_objects.append(self.save_new(form, commit=commit))
    331332        return new_objects
    332333
    333334    def add_fields(self, form, index):
  • django/newforms/forms.py

     
    191191                return False
    192192        return True
    193193
    194     def full_clean(self):
     194    def full_clean(self, keep_invalid=False):
    195195        """
    196196        Cleans all of self.data and populates self._errors and
    197197        self.cleaned_data.
     
    219219            self.cleaned_data = self.clean()
    220220        except ValidationError, e:
    221221            self._errors[NON_FIELD_ERRORS] = e.messages
    222         if self._errors:
     222        if not keep_invalid and self._errors:
    223223            delattr(self, 'cleaned_data')
    224224
    225225    def clean(self):
  • tests/regressiontests/forms/widgets.py

     
    292292>>> w.value_from_datadict({}, {}, 'testing')
    293293False
    294294
     295The CheckboxInput widget will always be empty when there is a False value
     296>>> w.is_empty(False)
     297True
     298>>> w.is_empty(True)
     299False
     300
    295301# Select Widget ###############################################################
    296302
    297303>>> w = Select()
     
    453459<option value="3" selected="selected">No</option>
    454460</select>
    455461
     462The NullBooleanSelect widget will always be empty when Unknown or No is selected
     463as its value.  This is to stay compliant with the CheckboxInput behavior
     464>>> w.is_empty(False)
     465True
     466>>> w.is_empty(None)
     467True
     468>>> w.is_empty(True)
     469False
     470
    456471""" + \
    457472r""" # [This concatenation is to keep the string below the jython's 32K limit].
    458473# SelectMultiple Widget #######################################################
     
    895910>>> w.render('name', ['john', 'lennon'])
    896911u'<input id="bar_0" type="text" class="big" value="john" name="name_0" /><br /><input id="bar_1" type="text" class="small" value="lennon" name="name_1" />'
    897912
     913The MultiWidget will be empty only when all widgets are considered empty.
     914>>> w.is_empty(['john', 'lennon'])
     915False
     916>>> w.is_empty(['john', ''])
     917False
     918>>> w.is_empty(['', ''])
     919True
     920>>> w.is_empty([None, None])
     921True
     922
    898923# SplitDateTimeWidget #########################################################
    899924
    900925>>> w = SplitDateTimeWidget()
Back to Top