[Zope-dev] z3c.form: Problem validating file uploads

Jacob Holm jh at improva.dk
Wed Apr 22 08:48:23 EDT 2009


Michael Howitz wrote:
> Am 12.04.2009 um 15:12 schrieb Michael Howitz:
>> Hi,
>>
>> I'm using a trunk version of z3c.form and have the following  
>> situation:
>> In my interface I have a zope.schema.Bytes field.
>> z3c.form.converter.FileUploadDataConverter.toFieldValue returns
>> z3c.form.interfaces.NOT_CHANGED when I do not upload a file.
>> z3c.form.validator.SimpleFieldValidator.validate fails later on as the
>> value (z3c.form.interfaces.NOT_CHANGED) is not of type str (which is
>> required by the Bytes field).
>> I created a branch in svn to show the behavior. (z3c.form/branches/
>> icemac_validate_NOT_CHANGED)
>>
>> I'm not sure how to fix this generally, some possible solutions come
>> to my mind, but each idea has its own problems:
>>
>> 1) Create a special validator for zope.schema.Bytes +
>> z3c.form.interfaces.IFileWidget which knows how to handle NOT_CHANGED.
>>    This does not seem to be a really general solution and might have
>> the same problems like the following ideas.
>>
>> 2) When z3c.form.validator.SimpleFieldValidator.validate is called
>> with NOT_CHANGED as value, try to look up the value on the context
>> object.
>>    This fails on AddForms as the context there is the parent object.
>>
>> 3) When z3c.form.validator.SimpleFieldValidator.validate is called
>> with NOT_CHANGED as value, do not validate hoping the previous value
>> was valid.
>>    This approach fails with AddForms, too, when the Bytes field is
>> required. (The missing-value-error does not get raised.)
>>
>> Anyone having an idea for a possibly working solution?
> 
> As I got no responsed, I'd like to put this issue into z3c.form's  
> bugtracker. But which is the correct one?
> https://bugs.launchpad.net/zope3/ ?
> 

I don't know about the right tracker for this, but I think the right 
solution is 2) except that when widget.ignoreContext is True the default 
value should be looked up and validated instead.  In other words, change 
z3c.form.validator.SimpleFieldValidator.validate to something like this 
(untested):

def validate(self, value):
     """See interfaces.IValidator"""
     context = self.context
     request = self.request
     view = self.view
     field = self.field
     widget = self.widget
     if context is not None:
         field = field.bind(context)
     if value is interfaces.NOT_CHANGED:
         if (interfaces.IContextAware.providedBy(widget) and
             not widget.ignoreContext):
             # get value from context
             value = zope.component.getMultiAdapter(
                 (context, field),
                 interfaces.IDataManager).query()
         else:
             value = interfaces.NO_VALUE
         if value is interfaces.NO_VALUE
             # look up default value
             value = field.default
             adapter = zope.component.queryMultiAdapter(
                 (context, request, view, field, widget),
                 interfaces.IValue, name='default')
             if adapter:
                 value = adapter.get()
     return field.validate(value)

Unless I am missing something, the above code should compute the same 
value as z3c.form.widget.Widget.update would when ignoreRequest is True. 
   Thus effectively converting NOT_CHANGED into the "existing" value 
before validating,

Hope this helps
- Jacob



More information about the Zope-Dev mailing list