Search code examples
plonedexterity

ComponentLookupError when trying to create new dexterity objects


I'm following a tutorial about manipulating dexterity content objects. It explains how to create objects.

from zope.component import createObject
context = createObject('example.type')

But I'm not sure what to put instead example.type. I tried using IProduct, degu.product.IProduct and degu.Product. But all of them raise a ComponentLookupError.

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/daniel/.buildout/eggs/zope.component-3.9.5-py2.6.egg/zope/component/_api.py", line 220, in createObject
    return getUtility(IFactory, __factory_name, context)(*args, **kwargs)
  File "/home/daniel/.buildout/eggs/zope.component-3.9.5-py2.6.egg/zope/component/_api.py", line 169, in getUtility
    raise ComponentLookupError(interface, name)
ComponentLookupError: (<InterfaceClass zope.component.interfaces.IFactory>, 'degu.commerce.product.IProduct')

Solution

  • You need to use the same name that you used in the the Dexterity FTI registration.

    You can verify what names are registered in the portal_types tool:

    from Products.CMFCore.utils import getToolByName
    
    typestool = getToolByName(context, 'portal_types')
    print typestool.listContentTypes()
    

    or visit the portal_types tool in the ZMI in your browser and look at the list of types there; they are listed as typeid (Type Title) in the tool. If your type isn't listed there ensure that you properly registered your type first.

    Note that for this to work, you need the local component manager set up correctly. Normally, this happens automatically, but if you are using a bin/instance run script or use bin/instance debug, that doesn't happen. You need to do that manually in that case:

    from zope.app.component.hooks import setSite
    from Testing.makerequest import makerequest
    
    app = makerequest(app)
    site = app[site_id]
    setSite(site)
    

    You may also want to set a current user:

    from AccessControl.SecurityManagement import newSecurityManager
    
    user = app.acl_users.getUser('admin').__of__(site.acl_users)
    newSecurityManager(None, user)