[Product-Developers] Re: Dexterity sub-objects issues

athomerson athomerson at sympatico.ca
Thu Jan 28 03:34:07 UTC 2010



Martin Aspeli wrote:
> 
> athomerson wrote:
>> I am starting to use Dexterity and I have run into a couple of issues.  I
>> have created a content schema (in client.py) and defined a sub-object in
>> it
>> like so:
>>
>>      emails = schema.List(
>>              title=_(u"Email Addresses"),
>>              value_type = schema.Object(title=u'Emails',
>>                                         schema=IEmailSubObject),
>>              required=False,
>>          )
>> I then created email.py with the following:
>>
>> @grok.provider(IContextSourceBinder)
>> def emailTypes(context):
>>
>>      terms = []
>>
>>      pprop = getToolByName(context, 'portal_properties')
>>      for t in pprop.client_properties.email_types:
>>          terms.append(SimpleVocabulary.createTerm(t, str(t), t))
>>      return SimpleVocabulary(terms)
>>
>> class IEmailSubObject(Interface):
>>      email_type = schema.Choice(
>>              title=_(u"Email type"),
>>              source=emailTypes,
>>              required=True,
>>          )
>>      email_address = schema.TextLine(
>>          title=_(u"Email address"),
>>          required=True,
>>          )
>> This gives me an error "TypeError: iterable argument required".
> 
> Please provide the full traceback when you report an error, it makes it 
> easier to see what's going on. For example, you haven't told us when you 
> get this error. On startup? On the add form? On an edit form? On the view?
> 
> It happens on both the add and the edit form. Here is the traceback:
> 2010-01-27 21:29:40 ERROR Zope.SiteErrorLog 1264645780.510.261268287683
> http://l
> ocalhost:50080/test1/test-folder/++add++ins.client.client
> Traceback (innermost last):
>   Module ZPublisher.Publish, line 119, in publish
>   Module ZPublisher.mapply, line 88, in mapply
>   Module ZPublisher.Publish, line 42, in call_object
>   Module plone.z3cform.layout, line 56, in __call__
>   Module plone.z3cform.layout, line 50, in update
>   Module plone.z3cform.fieldsets.extensible, line 59, in update
>   Module z3c.form.group, line 134, in update
>   Module z3c.form.group, line 47, in update
>   Module z3c.form.group, line 43, in updateWidgets
>   Module z3c.form.field, line 276, in update
>   Module z3c.form.browser.multi, line 61, in update
>   Module z3c.form.browser.widget, line 70, in update
>   Module z3c.form.widget, line 84, in update
>   Module z3c.form.widget, line 402, in extract
>   Module z3c.form.widget, line 294, in getWidget
>   Module z3c.form.browser.widget, line 70, in update
>   Module z3c.form.object, line 213, in update
>   Module z3c.form.widget, line 88, in update
>   Module z3c.form.object, line 259, in set
>   Module z3c.form.object, line 229, in applyValue
>   Module z3c.form.validator, line 67, in validate
>   Module zope.schema._bootstrapfields, line 140, in validate
>   Module zope.schema._field, line 327, in _validate
> TypeError: iterable argument required
> 
>> Debuging shows that we pass through  zope.schema._field
> 
> That file is big. You need to explain which line, and show the 
> surrounding code, if you want to reference it.
> 
> I put a breakpoint at line 327 of zope.schema._field (3.6.0).
>     def _validate(self, value):
>         # Pass all validations during initialization
>         if self._init_field:
>             return
>         super(Choice, self)._validate(value)
>         vocabulary = self.vocabulary
>         if vocabulary is None:
>             vr = getVocabularyRegistry()
>             try:
>                 vocabulary = vr.get(None, self.vocabularyName)
>             except VocabularyRegistryError:
>                 raise ValueError("Can't validate value without
> vocabulary")
> *       if value not in vocabulary:
>             raise ConstraintNotSatisfied(value)
> The first two times the breakpoint is reached "vocabulary" is a
> zope.schema.vocabulary.SimpleVocabulary object. The third time the
> breakpoint is reached "vocabulary" is an emailTypes function and the above
> error occurs.
> 
> 
>> three times and the
>> third time the self.vocabulary is no longer a vocabulary! This seems
>> similar
>> to the bug (340416) Martin reported on zope3.
> 
> Please link to the bug if you want to reference it.
> 
> Sorry. The bug report is  https://bugs.launchpad.net/zope3/+bug/340416
> here 
> 
>> If I change "email_type = schema.Choice(" to "email_type =
>> schema.TextLine("
>> (and remove "source=emailTypes,") I get a generic error which seems to be
>> caused by the fact that IEmailSubObject is returning a list rather than
>> an
>> object.
> 
> I don't understand the last sentence.
> 
> On both the add and edit form I get the error message "The system could
> not process the given value." on the form twice but no other information. 
> I set a breakpoint at line 93 of z3c.form.error.py (2.2.0) to trap the
> error message.  I then went back up the call stack to find where the error
> occurred.  The error seems to happen in z3c.form.widget line 338.  From
> z3c.form.widget:
> 
>     def applyValue(self, widget, value=interfaces.NO_VALUE):
>         """Validate and apply value to given widget.
> 
>         This method gets called on any multi widget value change and is
>         responsible for validating the given value and setup an error
> message.
> 
>         This is internal apply value and validation process is needed
> because
>         nothing outside this multi widget does know something about our
>         internal sub widgets.
>         """
>         if value is not interfaces.NO_VALUE:
>             try:
>                 # convert widget value to field value
>                 converter = interfaces.IDataConverter(widget)
>                 fvalue = converter.toFieldValue(value)
>                 # validate field value
>                 zope.component.getMultiAdapter(
>                     (self.context,
>                      self.request,
>                      self.form,
>                      getattr(widget, 'field', None),
>                      widget),
>                     interfaces.IValidator).validate(fvalue)
>                 # convert field value to widget value
>                 widget.value = converter.toWidgetValue(fvalue)
>             except (zope.schema.ValidationError, ValueError), error:
>                 # on exception, setup the widget error message
>                 view = zope.component.getMultiAdapter(
>                     (error, self.request, widget, widget.field,
>                      self.form, self.context),
> interfaces.IErrorViewSnippet)
> *               view.update()
>                 widget.error = view
>                 # set the wrong value as value
>                 widget.value = value
> self is <MultiWidget 'form.widgets.emails>
> widget is <ObjectWidget 'form.widget.emails.0>
> value is {'email_address':u'jdoe at home.com', 'email_type':u'Primary'}
> When the 'try' block is executed, "converter" is <ObjectConverter converts
> from Object to ObjectWidget>
> It appears to fail on the "fvalue = converter.toFieldValue(value)"
> statement. 
> 
>> Am I missing something or am I trying to do something with Dexterity that
>> it
>> is not ready for?
> 
> I don't know yet - you need to be a bit more specific before we can find 
> out what's going.
> 
> I apologize for not being specific enough.  I didn't know what was
> relevant
> I am running:
>     *  Plone 3.3.1
>     * CMF 2.1.2
>     * Zope (Zope 2.10.9-final, python 2.4.4, win32)
>     * Python 2.4.4 (#71, Oct 18 2006, 08:34:43) [MSC v.1310 32 bit
> (Intel)]
>     * PIL 1.1.5
> Debugging with WingIDE.
> 
> .  
> In general, I'd say that using a List with an Object field as a value 
> type is not a very common thing to do, mainly because the UI for that is 
> pretty rough in z3c.form, and the implications for how the form works 
> are that you probably need to store things in the session. Most people 
> model a one-to-many like this like a container type (the one) with 
> children (the many).
> 
> I considered storing the email type as a child but I thought that with
> only two fields it was more like the DataGridField.  If this ends up too
> complicated that is probably what I will do.  I do think this is the more
> elegant solution and I don't mind spending some time and effort to resolve
> this issue.  I will be more than happy to provide any information that
> would clarify things.
> 
> Allen
> 
> 
> Martin
> 
> -- 
> Author of `Professional Plone Development`, a book for developers who
> want to work with Plone. See http://martinaspeli.net/plone-book
> 
> 
> _______________________________________________
> Product-Developers mailing list
> Product-Developers at lists.plone.org
> http://lists.plone.org/mailman/listinfo/product-developers
> 
> 

-- 
View this message in context: http://n2.nabble.com/Dexterity-sub-objects-issues-tp4469111p4471260.html
Sent from the Product Developers mailing list archive at Nabble.com.




More information about the Product-Developers mailing list