It's don't get called when I save or change object. I looked a little in Model class and I can't find any invocation of
the validate() method. Is it available for general use or I must wait a little bit more ;) ?
Also, I presume (from reading code) that when I call super(Foo, self).validate() all fields are converted to the
appropriate python objects so I can use something like this in my model validate method:
errdict = super(Foo, self).validate()
if self.type != self.category.type:
if 'category' in errdict:
errdict['category'].append(_("Invalid category for this type!"))
else:
errdict['category']= [_("Invalid category for this type!")]
return errdict
where self.category is ForeignKey to another object.
Or I just getting this completely wrong :) ?
--
Nebojša Đorđević - nesh
Studio Quattro - Niš - SCG
http://studioquattro.biz/
http://djnesh.blogspot.com/ | http://djnesh-django.blogspot.com/ | http://djangoutils.python-hosting.com/
Registered Linux User 282159 [http://counter.li.org]
Yeah, it doesn't get called on save() yet. It's not really intended
for general use, because only a few of the Field classes have the
validation method implemented. Help coding this up would be *much*
appreciated!
> Also, I presume (from reading code) that when I call super(Foo, self).validate() all fields
> are converted to the
> appropriate python objects so I can use something like this in my model validate method:
>
> errdict = super(Foo, self).validate()
> if self.type != self.category.type:
> if 'category' in errdict:
> errdict['category'].append(_("Invalid category for this type!"))
> else:
> errdict['category']= [_("Invalid category for this type!")]
> return errdict
>
> where self.category is ForeignKey to another object.
>
> Or I just getting this completely wrong :) ?
That should indeed work.
Adrian
--
Adrian Holovaty
holovaty.com | djangoproject.com
I'll will try to help if I can.
Currently implemented validate() methods (in EmailField, IPAddressField and PhoneNumberField) just call
validators.isValidFOO(field_data, all_data) and, for example, validate method for PositiveIntegerField will look
something like this:
def validate(self, field_data, all_data):
if i < 0:
raise ValidationError, gettext("Positive numbers only!")
From docstring in Field.validate() I can assume that field_data is already converted to int and that validate() will not
be called if field_data is invalid integer.
I take a (very) fast look at the code and here is a list of the fields that requires validate method (IMHO), for other
fields to_python is already performed some type of validation (i.e. IntegerField):
* CharField - check if maxlength is not exceeded
* CommaSeparatedIntegerField - check format (\d+,)+
* FloatField - check max_digits?
* ImageField - check image dimensions if given
* PositiveIntegerField/PositiveSmallIntegerField - assert that field_data >= 0
* SlugField - check that field_data conforms to slug format ([a-z]_\-)+
* URLField - check that field_data points to a valid URL
* USStateField - ??
* XMLField - probably validate against Relax NG compact schema?
* ForeignKey - check if given id exist in related table (or to_python is already checked that while converting?)
* OneToOneField - check that no other field has same id
* ManyToManyField - like ForeignKey, but for all records in related table
This applies to all fields:
* validate_full will take care of blank fields, but how about NOT NULL fields?
* check uniqueness for the fields with unique=True and also for the unique_for_FOO?
* finally run through the validator_list to perform user requested validation?
Lot's of this functionality is already implemented with existing validators so validate() method will first call
appropriate function/class from validators.py and then perform any additional validation.
Anything else?
> That should indeed work.
Great!!! This type of validation is just what I expect in the best Python ORM ;).
Each field type is responsible for two types of validation -- type
coercion (in the to_python() method) and actual validation (in the
validate() method) -- so the implementation depends on the field.
> I take a (very) fast look at the code and here is a list of the fields that requires validate method (IMHO), for other
> fields to_python is already performed some type of validation (i.e. IntegerField):
>
> * CharField - check if maxlength is not exceeded
> * CommaSeparatedIntegerField - check format (\d+,)+
> * FloatField - check max_digits?
> * ImageField - check image dimensions if given
> * PositiveIntegerField/PositiveSmallIntegerField - assert that field_data >= 0
> * SlugField - check that field_data conforms to slug format ([a-z]_\-)+
> * URLField - check that field_data points to a valid URL
> * USStateField - ??
> * XMLField - probably validate against Relax NG compact schema?
> * ForeignKey - check if given id exist in related table (or to_python is already checked that while converting?)
> * OneToOneField - check that no other field has same id
> * ManyToManyField - like ForeignKey, but for all records in related table
>
> This applies to all fields:
> * validate_full will take care of blank fields, but how about NOT NULL fields?
> * check uniqueness for the fields with unique=True and also for the unique_for_FOO?
> * finally run through the validator_list to perform user requested validation?
>
> Lot's of this functionality is already implemented with existing validators so validate() method will first call
> appropriate function/class from validators.py and then perform any additional validation.
That's pretty much it. Let me know if you decide to take this on...We
should coordinate which fields we're taking.
I giving it a try, see ticket http://code.djangoproject.com/ticket/1553 for details.
p.s. being in different time zones have some advantages ;)
For start I attached unit-tests for field classes to the ticket.
I'm attached new unit-tests and the first version of the patch to the ticket
(http://code.djangoproject.com/ticket/1553). Take a look.
Not implemented:
* FileField
* ImageField
I'm not sure what to_python should return for this type of fields, file path (MEDIA_ROOT relative) or the file itself
(file-like object)?
* FilePathField
* PhoneNumberField (trivial: validators.isValidPhone, extend to accept regex for phone_re to accommodate other phone
formats)
* USStateField (trivial: validators.isValidUSState)
* XMLField (hmmm, validators.RelaxNGCompact I presume)
* ForeignKey
* ManyToManyField
For them I don't have a clue what to do. How to convert field_data (in to_python) to actual object(s)?
* OneToOneField
As above with additional check that no other record can have the same ID.
Also, all fields have not checked for cases where unique=True or unique_for_* is set. I must somehow get hold (in
validate()) of the model default manager to be able execute query to check that this value don't already exists for
given criteria.