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