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.
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,
)