How does queryContentType work?

I have a product (export.policy) whose setup handler is being used to export information from existing content.
I'm trying to follow instructions for introspecting an interface.
https://docs.plone.org/4/en/external/plone.app.dexterity/docs/reference/manipulating-content-objects.html?highlight=introspect#object-introspection

In my setup handler function, I have this:

def setup_various(context):
    ...
    catalog = api.portal.get_tool(name='portal_catalog')
    brains = catalog.searchResults({'portal_type':'my.product.contenttype'})
    for i in brains:
        obj = i.getObject()
        schema = queryContentType(obj)
        fields = getFieldsInOrder(schema)
        for f in fields:
            print f

Unfortunately, it breaks at fields = getFieldsInOrder(schema).
I tried printing the schema, but its returning None.
And calling getFieldsInOrder get this error:

2018-08-08 07:24:39 ERROR Zope.SiteErrorLog 1533727479.590.139046844079 http://localhost:8080/Plone/portal_quickinstaller/reinstallProducts
Traceback (innermost last):
Module ZPublisher.Publish, line 138, in publish
Module ZPublisher.mapply, line 77, in mapply
Module ZPublisher.Publish, line 48, in call_object
Module , line 6, in reinstallProducts
Module AccessControl.requestmethod, line 70, in _curried
Module Products.CMFQuickInstallerTool.QuickInstallerTool, line 784, in reinstallProducts
Module , line 3, in installProducts
Module AccessControl.requestmethod, line 70, in _curried
Module Products.CMFQuickInstallerTool.QuickInstallerTool, line 686, in installProducts
Module Products.CMFQuickInstallerTool.QuickInstallerTool, line 602, in installProduct

  • traceback_info: ('export.policy',)
    Module Products.GenericSetup.tool, line 388, in runAllImportStepsFromProfile
  • traceback_info: profile-export:policy:default
    Module Products.GenericSetup.tool, line 1433, in _runImportStepsFromContext
    Module Products.GenericSetup.tool, line 1245, in _doRunImportStep
  • traceback_info: export.policy
    Module export.policy.setuphandlers, line 16, in setup_various
    Module zope.schema._schema, line 42, in getFieldsInOrder
    Module zope.schema._schema, line 32, in getFields
    TypeError: 'NoneType' object is not iterable

Why is queryContentType returning None for me?

Likely, because your object does not provide an interface which provides IContentType.

To learn, how queryContentType works, you can looks at its source.

There is an important change in the implementation of Plone content objects: formerly, Plone objects have been implemented with Archetypes; now they are implemented with dexterity. The documentation you have cited might work only for one of those implementation variants -- likely, dexterity based objects.

1 Like

Thank you for your response
I apologize my response is late.

I took a look at it and the content type I am working with is a dexterity type, so I am confused unfortunately as to why it isn't working with my content type. Maybe something is preventing IContentType from being implemented. I'll try with another dexterity content type.

However, if it means anything, I found an alternative to getting a dexterity type's schema.

from plone.dexterity.interfaces import IDexterityFTI
from zope.component import getUtility

def getFieldsFromPortalType(portal_type):

    fields = []
    dxti = getUtility(IDexterityFTI,name=portal_type)
    schema = dxti.lookupSchema()
    
    for f in getFieldsInOrder(schema):
        fields.append(f[0])

    #additional code for iterating behaviors from plone docs


m_fields = getFieldsFromPortalType('my.object.mytype')

This works alright as an alternative, but I think queryContentType is cleaner?

FYI: IContentType is used for auto-generated DX schemas, but you'll have to provide it manually for custom content types.

See http://plone.293351.n2.nabble.com/do-Dexterity-objects-provide-IContentType-td7571461.html#a7571462

1 Like