Optional field in schema interface

class IUser(Interface):
    userid = schema.TextLine(
        title=_("User id"),

    email = schema.TextLine(

    optional_type = schema.Choice(
        title=_(u"User type"),

In a plone add-on I have something like this defined. The add-on need to be used for multiple websites. Sometimes the optional_type field is needed sometimes not. user_types is saved in portal_vocabularies. I want the field to be used only when the vocabulary exists and I want it to be ignored when the definition is missing.

I mean, I want this field to work for websites where it is used, but the user schema also to work in other case. For the moment I receive this error: ComponentLookupError: (<InterfaceClass zope.schema.interfaces.IVocabularyFactory>, 'user_types').

You can suggest any solution to skip this error without creating the vocabulary. Thanks. :slight_smile:

When I understand you right, then you want the field optional_type to be present in some cases (when portal_vocabularies satisfies a condition) and to be missing in other cases. This is not directly supported by zope.schema.
You will need to give your add-on some logic that chooses an interface with optional_type in some cases and another one without it in other cases.

Should you be ready to have the field in all cases, then you must in all cases provide the vocabulary. However, what you specify in the Choice field via vocabulary is in fact not the name of a vocabulary but the name of a vocabulary factory, i.e. a function that returns the real vocabulary. You can define the factory in such a way, that it returns a default vocabulary in the cases where you do not need the field. You can then set required=False and check in a constraint that the field was actually specified in the cases where this is necessary.

1 Like

Great. Thank you!

in fact not the name of a vocabulary but the name of a vocabulary factory

Saved my day. :slight_smile: