Personal tools
You are here: Home Lists ZPUG DC List Archives 2005 2005-07 Problem using archetype post_validate / David Diskin <david.diskin@verizon.net>
Navigation
Log in


Forgot your password?
New user?
Mailing Lists
You can read our ZPUGDC mailing list archives online.
You can subscribe to our mailing list:
Book Review

The Definitive Guide to Plone

Reviewer: joel
 

Problem using archetype post_validate / David Diskin <david.diskin@verizon.net>

Problem using archetype post_validate
David Diskin <david.diskin(at)verizon.net>
2005-07-26 21:31:12 [ FULL ]
I posted the following message to both Plone users and archetype  
users with no real help forthcoming.  It seems like a pretty  
straightforward archetype validation use case, but I'm completely  
stumped.  In addition to trying post_validate, I have also tried to  
use pre_validate with the same variations as listed below with  
post_validate, but with the same lack of success.  Either this is  
broken or I'm not really grokking this.  I also am not sure when pre  
and post_validate get invoked and why after correctly handling the  
error (at least in variation 4 below) and returning to the form, I  
still get the error even after I have made the correction to the form.

I know there must be someone in the Plone world who can help me on  
this.  I'm a bit frustrated that I haven't found any help so far.

I am using Plone 2.0.5 and Archetypes 1.3.3-final.

Appreciate any advice.

Thanks,

David

Begin forwarded message:
[...]
==============================
David Diskin, david.diskin(at)verizon.net
Attachments: 
text.html text/html - 16777 Bytes

Re: [ZPUGDC] Problem using archetype post_validate / Matthew T.Kromer <MATTHEW.T.KROMER@saic.com>

Re: [ZPUGDC] Problem using archetype post_validate
Matthew T.Kromer <MATTHEW.T.KROMER(at)saic.com>
2005-07-27 08:39:40 [ FULL ]
OK.  First, apologies for a rather lengthy reply, since I'm going to 
include code snippets.

You do not need to use pre- and post- validation hooks.  You should 
write your own validation class and register it with archetypes and 
your specific content type as a validator.


To import the necessary things, your module which contains the 
validator must import:

from Products.validation.interfaces import ivalidator
from Products.Archetypes.Registry import registerValidator

then, you create a validation class.  Here's a sample one

class ServiceValidator:
     __implements__ = (ivalidator,)
     def __init__(self, name, title='', description=''):
         self.name = name
         self.title = title or name
         self.description = description

     def __call__(self, value, *args, **kwargs):
         if not value:
             return ("Validation Failed(%s): value is "
                     "empty or not informed (%s)." % (self.name, 
repr(value)))

         if not kwargs.has_key('instance'):
             return ("Validation Failed(%s): instance object not found."
                      % (self.name,))

         instance = kwargs['instance']
         REQUEST = kwargs['REQUEST']

         doctype = None
         if REQUEST: doctype = REQUEST.form.get('doctype',None)
         if doctype is None:
             doctype = getattr(instance,'doctype',None)
         if doctype is None:
             return ("Validation Failed(%s):  document type not found."
                      % (self.name,))

         if doctype == 'TTSARB' or doctype == 'DDL':
             if value != 'Dept of Navy':
                 return ("Validation Failed(%s):  Documents of this type 
"
                         "must be assigned to Dept of Navy" % 
(self.name, ))


Finally, you must register the validator with Plone (this step here 
includes instatiating an instance of a validator and registering it).

registerValidator(ServiceValidator('isValidService'))

You'll notice the vaildator is called with a number of keyword 
arguments.  One of them is 'instance=' which is the instance of the 
archetype its being called to validate.  Thus, you can have your 
validator inspect the contents of other fields.  Notice that the 
posting in the request for the 'doctype' field overrides the current 
field value, since both fields may be updated simultaneously.   This 
particular validator says "No, you can't assign a document of TTSARB or 
DDL to anyone other than the Navy."   Its hung off of only one of the 
two fields, since in my case, its only that field that has a dependancy 
on the other (there isn't a mutual dependancy).



On Jul 26, 2005, at 10:33 PM, David Diskin wrote:
[...][...][...]

Re: [ZPUGDC] Problem using archetype post_validate / David Diskin <david.diskin@verizon.net>

Re: [ZPUGDC] Problem using archetype post_validate
David Diskin <david.diskin(at)verizon.net>
2005-07-27 13:14:11 [ FULL ]
hi Matthew,

Thanks so much for the thorough reply.  I have a couple of questions  
about your email.  Please see [DD] below.  Thanks again,

David

On Jul 27, 2005, at 9:41 AM, Matthew T.Kromer wrote:
[...]

[DD] Where should this class be placed?  McKay (p. 405) says to add  
it to products/validation/validators
[...]

[DD] So, i should be able to access my 2 fields by getattr 
(instance,'field1',None) and getattr(instance,'field2',None) - is  
that correct?
[...]

Does this go in the __init__ module?
[...][...]
>>> From: David Diskin <david.diskin(at)verizon.net>
>>> Date: July 26, 2005 12:58:38 PM EDT
>>> To: plone-users(at)lists.sourceforge.net
>>> Subject: [Plone-users] New problem with using post_validate
>>>
>>>
>>> I solved my initial problem with post_validate and now my (first) 

>>> AT product installs correctly, but, I still can't get the correct 

>>> behavior I need.
>>>
>>> I'm trying to validate form entry for an AT product I developed.  
>>> To do this I need to look at 2 boolean fields together. It is an  
>>> error if both field1 and field2 are False - i.e. unchecked in the 

>>> Boolean widget. I am trying to use the post_validate hook as  
>>> follows:
>>>
>>>
>>> Here's the code for the 2 fields in the schema:
>>>
>>>   BooleanField('field1',
>>>   widget=BooleanWidget(
>>>   label='We will attend event 1',
>>>   description='Check if you will attend event 1.',
>>>   ),
>>>   schemata='Member Ticket Request',
>>>   default=True,
>>>   ),
>>>
>>>   BooleanField('field2',
>>>   widget=BooleanWidget(
>>>   label='We will attend event 2',
>>>   description='Check if you will attend event 2.',
>>>   ),
>>>   schemata='Member Ticket Request',
>>>   default=True,
>>>   ),
>>>
>>>
>>>
>>> I have tried several variations as follows for the post_validate:
>>>
>>> 1. def post_validate(self,REQUEST,errors):
>>>   b_field1 = REQUEST.form.get('field1',None)
>>>   b_field2 = REQUEST.form.get('field2',None)
>>>   if not (b_field1 or b_field2)
>>>   errors['field1'] = "You must select either field 1 or field 2"
>>>
>>> With this variation, the error message does not appear even if  
>>> field 1 and field 2 are unchecked.
>>>
>>> 2. def post_validate(self,REQUEST,errors):
>>>   b_field1 = REQUEST.get('field1',None)
>>>   b_field2 = REQUEST.get('field2',None)
>>>   if not (b_field1 or b_field2)
>>>   errors['field1'] = "You must select either field 1 or field 2"
>>>
>>> With this variation, the error message does not appear even if  
>>> field 1 and field 2 are unchecked.
>>>
>>> 3. def post_validate(self,REQUEST,errors):
>>>   b_field1 = REQUEST.get('field1')
>>>   b_field2 = REQUEST.get('field2')
>>>   if not (b_field1 or b_field2)
>>>   errors['field1'] = "You must select either field 1 or field 2"
>>>
>>> With this variation, the error message does not appear even if  
>>> field 1 and field 2 are unchecked.
>>>
>>> 4. def post_validate(self,REQUEST,errors):
>>>   b_field1 = self.getField1()
>>>   b_field2 = self.getField2()
>>>   if not (b_field1 or b_field2)
>>>   errors['field1'] = "You must select either field 1 or field 2"
>>>
>>> This variation behaves correctly when neither field 1 nor field 2 

>>> are checked - it displays the error message at field 1 on the  
>>> form. However, when I check one or both of field 1 or field 2 and 

>>> do another save, I incorrectly get the error message and am  
>>> returned to the form.  It seems that the new save does not  
>>> replace the original values for field 1 and field 2.
>>>
>>> Any ideas or suggestions would be greatly appreciated. Also an  
>>> explanation of how/when pre and post_validate are invoked would  
>>> be really helpful.
>>>
>>> Thanks,
>>>
>>> David
>>>
>>>
>>> ==============================
>>> David Diskin, david.diskin(at)verizon.net
>>>
>>>
>>>
>>> -------------------------------------------------------
>>> SF.Net email is sponsored by: Discover Easy Linux Migration  
>>> Strategies
>>> from IBM. Find simple to follow Roadmaps, straightforward
articles,
>>> informative Webcasts and more! Get everything you need to get up
to
>>> speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
>>> _______________________________________________
>>> Plone-users mailing list
>>> Plone-users(at)lists.sourceforge.net
>>> https://lists.sourceforge.net/lists/listinfo/plone-users
>>>
>>>[...][...]
==============================
David Diskin, david.diskin(at)verizon.net

Re: [ZPUGDC] Problem using archetype post_validate / Matthew T.Kromer <MATTHEW.T.KROMER@saic.com>

Re: [ZPUGDC] Problem using archetype post_validate
Matthew T.Kromer <MATTHEW.T.KROMER(at)saic.com>
2005-07-28 08:20:59 [ FULL ]
On Jul 27, 2005, at 2:16 PM, David Diskin wrote:
[...][...]

Make it  part of your primary AT product.   It's unlikely that you'll 
be making a specific validator that's also general purpose.  In any 
case, I find it preferable to package 'my stuff' as being distinct from 
trying to have a merge into the base of another product.  If you had 
commit privileges against the base validators the other might be 
acceptable, but whenever your validation is really just an extended 
portion of your archetype, then it makes no sense to package it 
separately.
[...][...]

Strictly you can access via instance.field1 and instance.field2 -- 
however, using getattr notation allows you to specify a default value 
in case the attribute does not exist, such that you can handle that 
condition cleanly.  For example, if you modify your archetype, any 
instances created before the modification may not have certain 
attributes.  Most OO code doesn't cope with very long object lifecycle 
persistence well, so the problems of "how do I make my persistent 
python objects evolve over time" aren't expounded on very well.
[...][...]


No, thats all part of your validation class module -- it can be 
imported by your Archetypes type module -- the only condition that 
holds is that the registerValidator has to occur before you register 
your Archetype, otherwise your archetype schema will not initialize 
because the validator name won't be defined yet.

Powered by Plone, the Open Source Content Management System

This site conforms to the following standards: