- to_python (field)
- validate (field)
- run_validators (field)
- clean (field)
- clean_<fieldname> (form)
- clean (form)
class MyBaseForm(forms.Form): base_field1 = forms.CharField() base_field2 = forms.CharField() def clean_base_field1(self): #(...) return self.cleaned_data['base_field1'] def clean_base_field2(self): #(...) return self.cleaned_data['base_field2'] class MyForm(MyBaseForm): field1 = forms.CharField() def clean_field1(self): #(...) return self.cleaned_data['field1']
All methods implemented in this example refer to step 5: clean_<fieldname>. So what would be the execution order if we try validating MyForm? Django manual states:
"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 its override) is run, then clean_<fieldname>(). Finally, once those two methods are run for every field, the Form.clean() method, or its override, is executed."
According to this statement, the expected order would be: clean_base_field1, clean_base_field2, field1. What if we don't like this order, should we rearrange the form definition? No such thing! There is a way change this order in a more elegant way. We may use fields.keyOrder to achieve it:
class MyForm(MyBaseForm): field1 = forms.CharField() def clean_field1(self): #(...) return self.cleaned_data['field1'] def __init__(self, *args, **kwargs): super(MyForm, self).__init__(*args, **kwargs) self.fields.keyOrder = ['base_field1', 'field1', 'base_field2']
You don't need to extend a form to use this. You may also specify a partial order (if there are to many fields to be named explicitly) by putting only a few field names in the array and extending it by a list comprehension generated from the remaining self.fields.keys().
Cheers!
~KR
It's working :) thanks!
ReplyDelete