pythonploneplone-5.x

plone - While in an edit form, what can cause portal catalog to fail in a source object for an autocomplete choice field?


I have a source object for a choice field that is an autocomplete widget and it relies on using portal catalog to find content based on the value passed in by the user. Unfortunately, while viewing an Edit form, the portal_catalog sometimes returns 0 results where it should be returning 1 result.

The function that should be returning 1 result is 'getTerm'. I did a print statement to see how many results it gets and to make sure the value being passed in is what the term's value should be. My print statement shows the value passed in is always the one that should be, but it doesn't always find the result. I am not sure why this is 'failing', when it works in the Add Form.

My Interface:

class IMyContentType(model.Schema):

    organization = schema.Choice(title='',
                                 source=Organizations(),
                                )

My object source:

class OrganizationsSource(object):
    implements(IQuerySource)

    def __init__(self,context):
        self.context = context

    def queryOrganizations(self,value):
        catalog = api.portal.get_tool(name='portal_catalog')
        brains = catalog.evalAdvancedQuery(
               AdvancedQuery.MatchRegexp('portal_type','Organization') &
               AdvancedQuery.MatchRegexp('Title',value+"*")
             )
        return [i.Title for i in brains]

    def __contains__(self,value):
        q = self.queryOrganizations(value)
        if len(q) > 0:
            return True
        else:
            return False

    def getTerm(self, value):
        q = self.queryOrganizations(value)
        #Where I check to see if it should be working
        #the value passed in is the one that should be
        print value, len(q)
        return SimpleTerm(title=q[0],value=q[0])

    def getTermByToken(self,token):
        return self.getTerm(token)

    def search(self,query_string):
        q = self.queryOrganizations(query_string)
        return [SimpleTerm(title=v,value=v,token=v) for v in q]

class Organizations(object):
    implements(IContextSourceBinder)

    def __init__(self):
        self.context = self

    def __call__(self, context):
        return OrganizationsSource(context)

Is this approach possible at all? Is there a different catalog I should be using?

I also tried in the getTerm function a simple searchResults instead of evalAdvancedQuery:

def getTerm(self,value):
    catalog = api.portal.get_tool(name='portal_catalog')
    brains = catalog.searchResults({'portal_type':'Organization',
                                   'Title':value,
                                 })
    return SimpleTerm(title=brains[0]['Title'],
                      value=brains[0]['Title'],
                  )

I was getting the same issue.

I am using Plone 5.1.


Solution

  • First of all, i would recommend you to use the ZCatalog and not AdvancedQuery. For what you are doing there is no reason to use AdvancedQuery. Just use the normal catalog thru the plone.api https://docs.plone.org/develop/plone.api/docs/content.html#find-content-objects Also make sure the user has the needed permissions to see the objects you are searching for.

    Example:

    from plone import api
    
    def query_organizations(self, search_term):
        search_term = search_term and search_term + '*' or ''
        documents = api.content.find(
            portal_type='Organization',
            Title=search_term,
        )