magic-removal: model validate() question(s)

4 views
Skip to first unread message

Nebojša Đorđević

unread,
Mar 28, 2006, 9:46:03 AM3/28/06
to django-d...@googlegroups.com
I just tried to use new model validate() method (R2571) but....

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]

Adrian Holovaty

unread,
Mar 28, 2006, 10:43:42 AM3/28/06
to django-d...@googlegroups.com
On 3/28/06, Nebojša Đorđević <ne...@studioquattro.co.yu> wrote:
> I just tried to use new model validate() method (R2571) but....
>
> 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 ;) ?

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

Nebojša Đorđević

unread,
Mar 28, 2006, 12:12:41 PM3/28/06
to django-d...@googlegroups.com
Adrian Holovaty wrote:
> 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!

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 ;).

Adrian Holovaty

unread,
Mar 28, 2006, 11:43:08 PM3/28/06
to django-d...@googlegroups.com
On 3/28/06, Nebojša Đorđević <ne...@studioquattro.co.yu> wrote:
> 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!")
>
> Fromdocstring 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.

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.

Nebojša Đorđević

unread,
Mar 29, 2006, 4:12:56 AM3/29/06
to django-d...@googlegroups.com
Adrian Holovaty wrote:
> 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 ;)

Nebojsa Djordjevic

unread,
Mar 30, 2006, 7:17:20 AM3/30/06
to django-d...@googlegroups.com
Nebojša Đorđević wrote:
> I giving it a try, see ticket http://code.djangoproject.com/ticket/1553 for details.

For start I attached unit-tests for field classes to the ticket.

Nebojsa Djordjevic

unread,
Mar 31, 2006, 4:10:45 PM3/31/06
to django-d...@googlegroups.com
Adrian Holovaty wrote:
> That's pretty much it. Let me know if you decide to take this on...We
> should coordinate which fields we're taking.

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.

Reply all
Reply to author
Forward
0 new messages