The purpose of web development frameworks is to make common web development tasks easier, or give them to you for free. A forms framework which requires custom code for password comparisons does not satisfy this fundamental requirement.
I've seen the test codes that tell you how to compare multiple fields by creating custom clean methods. Why should one have to do that every time you need to compare fields? It's a consequence of Newforms' architecture, and I think it should be changed. >From my inspection of the code, the architecture is as follows: Forms have fields, and forms have data. When a form has fields /and/ data, it also has BoundFields, special little objects that have access to both the field information and the data. This means that the field itself has no access to the data, or to the form, or to itself, which in turn means that common operations that require access to form data cannot be done from within the Field, which I feel is the proper place to put it to ensure reusability. What's wrong with modifying the Newforms architecture to enable fields to have access to form data? There are many ways of doing this, but I've implemented a naive method as below: class AwareForm(forms.Form): """ This behaves as a regular form, except it makes all fields aware of their corresponding forms.BoundField object through a bound_field attribute. """ def is_valid(self): for bound_field in self: bound_field.field.bound_field = bound_field return forms.Form.is_valid(self) This form enables fields to do all sorts of fun tricks, like the following example that could work for Password confirmation (warning, following example is not as DRY as it could be): class ConfirmCharField(forms.CharField): """ This field behaves exactly the same as the CharField that is given to the constructor as the field parameter, and it also validates that it matches the value of the field with the same name as this field minus "confirm_" This field must be named "confirm_<field>", where <field> is the name of the field to confirm. Since this relies on the name of the field and on the form data, this must be in an AwareForm. """ def __init__(self, field, error=u'This field must match the %s field.'): self.field = field self.error = error super(ConfirmCharField, self).__init__(max_length=field.max_length, min_length=field.min_length, required=field.required, widget=field.widget, label=field.label, initial=field.initial, help_text=field.help_text) def clean(self, value): "Validates that this field's value is the same as the field to confirm against" super(ConfirmCharField, self).clean(value) name = self.bound_field.name.replace('confirm_','') if value != self.bound_field.form[name].data: raise ValidationError(self.error) return value and this next example, which could work for unique username validation. class UniqueCharField(forms.CharField): """ This field behaves exactly the same as a CharField, except that it also validates that an object does not already exist in the database Since this relies on the name of the field, this must be in an AwareForm. """ def __init__(self, cls, error=u'This field must be unique.', *args, **kwargs): self.cls = cls self.error = error super(UniqueCharField, self).__init__(*args, **kwargs) def clean(self, value): """ Validates that this field's value does not already exist in the database for the given type """ super(UniqueCharField, self).clean(value) column = self.bound_field.name if len(self.cls.objects.extra(where=[column+'=\''+value +'\''])) != 0: raise ValidationError(self.error) return value Then you could have a form to, say, register a new user: class JoinForm(AwareForm): """ This is the form that prospective members use to sign up to the site """ username = UniqueCharField(cls=User, error="Another user has this username") email = forms.EmailField() password = forms.CharField(widget=PasswordInput(render_value=False)) confirm_password = ConfirmCharField(field=password, error="The passwords must match") Anyone have any thoughts? Thanks, Ian --~--~---------~--~----~------------~-------~--~----~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---