Great stuff again Malcolm. Perhaps it should be rehashed a bit and put in the newforms docs under 'custom validation' ?
Just a thought :) regards, Simon On May 22, 12:11 am, Malcolm Tredinnick <[EMAIL PROTECTED]> wrote: > On Mon, 2007-05-21 at 14:00 -0500, Tim Chase wrote: > > > What is the "general way" to add your own validation to forms under > > > the newforms framework? > > > > Subclassing and adding in your clean_* methods? Using decorators or > > > the such around existing validation? Adding your own custom Field > > > objects and setting their "clean" methods? > > > My understanding (easily wrong, and appreciating correction if > > so) is that they are divergent concepts, each of which serves its > > own purpose. > > [...] > > > Perhaps > > one of the framework gurus could shed light on "the way it should > > be done"... > > Tim's explanation is mostly on the money. Since I have a "framework > guru" T-shirt around here somewhere (actually, I don't -- I want to get > a Django T-shirt one day), here's my understanding. > > There are three types of cleaning methods that are run during form > processing. These are all executed when you access Form.errors or call > call Form.full_clean() explicitly (or Form.is_valid(), which accesses > Form.errors). > > Any cleaning method can raise ValidationError if there is a problem with > the data it is processing, passing the relevant error message to the > ValidationError's constructor. If no ValidationError is raised, the > method should return a Python object for the cleaned (normalised) data. > > The three types of methods are: > > (1) The clean() method on a Field subclass. This is responsible > for cleaning the data in a way that is generic for that type of > field. For example, a FloatField will turn the data into a > Python float or raise a ValidationError. > > (2) The clean_fieldname() method -- where "fieldname" is > replaced with the name of the form field attribute. This method > does any cleaning that is specific to that particular attribute, > unrelated to the type of field that it is. In Matt's original > problem, clean_username() would be the right place to do any > uniqueness validation. You don't need a specific Username field > -- it's just a CharField, really -- but you want a > formfield-specific piece of validation and, possibly, cleaning. > > (3) The Form subclass's clean() method. This method can perform > any validation that requires access to multiple fields from the > form at once. This is where you might put in things to check > that if fieldA is supplied, fieldB must contain a valid email > address and the like. The data that this method returns is the > final cleaned_data attribute for the form, so don't forget to > return the full list of cleaned data if you override this method > (by default, Form.clean() just returns self.cleaned_data). > > Note that any errors raised by your Form.clean() override will > not be associated with any field in particular. They go into a > special "field" called "__all__", which you can access via > Form.non_field_errors() if you need to. You don't need to care > about __all__ at all (ha, ha!). > > These methods are run in the order given above, one field at a time. > That is, for each field in the form (in the order they are declared in > the form definition), the Field.clean() method (or it's override) is > run, then clean_<fieldname>(). Finally, once those two methods are run > for every field, the Form.clean() method, or it's override, is executed. > > Again, any of these methods can raise a ValidationError. For any field, > if step (1) raises a ValidationError, step (2) is not run, however, > steps (1) and (2) are run for all remaining fields. Regardless of the > results of steps (1) and (2), step (3) is always run. If step (3) raises > a ValidationError, self.cleaned_data will be an empty dictionary. > > The previous paragraph means that if you are overriding Form.clean(), > you should iterate through self.cleaned_data.items(), rather than > through the list of fields in the forms: not every field may end up > contributing to cleaned_data, because they may have raised > ValidationErrors themselves, so don't assume you have the data you need > by accessing the form fields directly -- always talk to > self.cleaned_data. > > Hopefully that clears up some of the mystery around the various form > validation phases. If somebody wants to write that up as a patch to the > newforms documentation, go crazy. > > Regards, > Malcolm --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---