def reindex(self, fields=None, unindex=False): """Asks a direct object reindexing. In most cases you don't have to reindex objects "manually" with this method. When an object is modified after some user action has been performed, Appy reindexes this object automatically. But if your code modifies other objects, Appy may not know that they must be reindexed, too. So use this method in those cases. """ if fields: # Get names of indexes from field names. indexes = [Search.getIndexName(name) for name in fields] else: indexes = None self.o.reindex(indexes=indexes, unindex=unindex)
def reindex(self, fields=None, unindex=False): '''Asks a direct object reindexing. In most cases you don't have to reindex objects "manually" with this method. When an object is modified after some user action has been performed, Appy reindexes this object automatically. But if your code modifies other objects, Appy may not know that they must be reindexed, too. So use this method in those cases. ''' if fields: # Get names of indexes from field names. indexes = [Search.getIndexName(name) for name in fields] else: indexes = None self.o.reindex(indexes=indexes, unindex=unindex)
def executeQuery(self, contentType, searchName=None, startNumber=0, search=None, remember=False, brainsOnly=False, maxResults=None, noSecurity=False, sortBy=None, sortOrder='asc', filterKey=None, filterValue=None, refField=None): '''Executes a query on a given p_contentType (or several, separated with commas) in Plone's portal_catalog. If p_searchName is specified, it corresponds to: 1) a search defined on p_contentType: additional search criteria will be added to the query, or; 2) "_advanced": in this case, additional search criteria will also be added to the query, but those criteria come from the session (in key "searchCriteria") and were created from search.pt. We will retrieve objects from p_startNumber. If p_search is defined, it corresponds to a custom Search instance (instead of a predefined named search like in p_searchName). If both p_searchName and p_search are given, p_search is ignored. This method returns a list of objects in the form of the __dict__ attribute of an instance of SomeObjects (see in appy.gen.utils). We return the __dict__ attribute instead of real instance: that way, it can be used in ZPTs without security problems. If p_brainsOnly is True, it returns a list of brains instead (can be useful for some usages like knowing the number of objects without needing to get information about them). If no p_maxResults is specified, the method returns maximum self.numberOfResultsPerPage. The method returns all objects if p_maxResults equals string "NO_LIMIT". If p_noSecurity is True, it gets all the objects, even those that the currently logged user can't see. The result is sorted according to the potential sort key defined in the Search instance (Search.sortBy). But if parameter p_sortBy is given, it defines or overrides the sort. In this case, p_sortOrder gives the order (*asc*ending or *desc*ending). If p_filterKey is given, it represents an additional search parameter to take into account: the corresponding search value is in p_filterValue. If p_refField is given, the query is limited to the objects that are referenced through it.''' # Is there one or several content types ? if contentType.find(',') != -1: portalTypes = contentType.split(',') else: portalTypes = contentType params = {'portal_type': portalTypes} if not brainsOnly: params['batch'] = True # Manage additional criteria from a search when relevant if searchName: # In this case, contentType must contain a single content type. appyClass = self.getAppyClass(contentType) if searchName != '_advanced': search = ClassDescriptor.getSearch(appyClass, searchName) else: fields = self.REQUEST.SESSION['searchCriteria'] search = Search('customSearch', **fields) if search: # Add additional search criteria for fieldName, fieldValue in search.fields.iteritems(): # Management of searches restricted to objects linked through a # Ref field: not implemented yet. if fieldName == '_ref': continue # Make the correspondance between the name of the field and the # name of the corresponding index. attrName = Search.getIndexName(fieldName) # Express the field value in the way needed by the index params[attrName] = Search.getSearchValue(fieldName, fieldValue) # Add a sort order if specified sortKey = search.sortBy if sortKey: params['sort_on'] = Search.getIndexName(sortKey, usage='sort') # Determine or override sort if specified. if sortBy: params['sort_on'] = Search.getIndexName(sortBy, usage='sort') if sortOrder == 'desc': params['sort_order'] = 'reverse' else: params['sort_order'] = None # If defined, add the filter among search parameters. if filterKey: filterKey = Search.getIndexName(filterKey) filterValue = Search.getSearchValue(filterKey, filterValue) params[filterKey] = filterValue # TODO This value needs to be merged with an existing one if already # in params, or, in a first step, we should avoid to display the # corresponding filter widget on the screen. # Determine what method to call on the portal catalog if noSecurity: catalogMethod = 'unrestrictedSearchResults' else: catalogMethod = 'searchResults' exec 'brains = self.portal_catalog.%s(**params)' % catalogMethod if brainsOnly: # Return brains only. if not maxResults: return brains else: return brains[:maxResults] if not maxResults: if refField: maxResults = refField.maxPerPage else: maxResults = self.appy().numberOfResultsPerPage elif maxResults == 'NO_LIMIT': maxResults = None res = SomeObjects(brains, maxResults, startNumber,noSecurity=noSecurity) res.brainsToObjects() # In some cases (p_remember=True), we need to keep some information # about the query results in the current user's session, allowing him # to navigate within elements without re-triggering the query every # time a page for an element is consulted. if remember: if not searchName: # It is the global search for all objects pf p_contentType searchName = contentType uids = {} i = -1 for obj in res.objects: i += 1 uids[startNumber+i] = obj.UID() self.REQUEST.SESSION['search_%s' % searchName] = uids return res.__dict__
def executeQuery(self, className, searchName=None, startNumber=0, search=None, remember=False, brainsOnly=False, maxResults=None, noSecurity=False, sortBy=None, sortOrder='asc', filterKey=None, filterValue=None, refObject=None, refField=None): '''Executes a query on instances of a given p_className (or several, separated with commas) in the catalog. If p_searchName is specified, it corresponds to: 1) a search defined on p_className: additional search criteria will be added to the query, or; 2) "_advanced": in this case, additional search criteria will also be added to the query, but those criteria come from the session (in key "searchCriteria") and were created from search.pt. We will retrieve objects from p_startNumber. If p_search is defined, it corresponds to a custom Search instance (instead of a predefined named search like in p_searchName). If both p_searchName and p_search are given, p_search is ignored. This method returns a list of objects in the form of the __dict__ attribute of an instance of SomeObjects (see in appy.gen.utils). We return the __dict__ attribute instead of real instance: that way, it can be used in ZPTs without security problems. If p_brainsOnly is True, it returns a list of brains instead (can be useful for some usages like knowing the number of objects without needing to get information about them). If no p_maxResults is specified, the method returns maximum self.numberOfResultsPerPage. The method returns all objects if p_maxResults equals string "NO_LIMIT". If p_noSecurity is True, it gets all the objects, even those that the currently logged user can't see. The result is sorted according to the potential sort key defined in the Search instance (Search.sortBy). But if parameter p_sortBy is given, it defines or overrides the sort. In this case, p_sortOrder gives the order (*asc*ending or *desc*ending). If p_filterKey is given, it represents an additional search parameter to take into account: the corresponding search value is in p_filterValue. If p_refObject and p_refField are given, the query is limited to the objects that are referenced from p_refObject through p_refField.''' # Is there one or several content types ? if className.find(',') != -1: classNames = className.split(',') else: classNames = className params = {'ClassName': classNames} if not brainsOnly: params['batch'] = True # Manage additional criteria from a search when relevant if searchName: # In this case, className must contain a single content type. appyClass = self.getAppyClass(className) if searchName != '_advanced': search = ClassDescriptor.getSearch(appyClass, searchName) else: fields = self.REQUEST.SESSION['searchCriteria'] search = Search('customSearch', **fields) if search: # Add additional search criteria for fieldName, fieldValue in search.fields.iteritems(): # Management of searches restricted to objects linked through a # Ref field: not implemented yet. if fieldName == '_ref': continue # Make the correspondance between the name of the field and the # name of the corresponding index. attrName = Search.getIndexName(fieldName) # Express the field value in the way needed by the index params[attrName] = Search.getSearchValue(fieldName, fieldValue) # Add a sort order if specified sortKey = search.sortBy if sortKey: params['sort_on'] = Search.getIndexName(sortKey, usage='sort') # Determine or override sort if specified. if sortBy: params['sort_on'] = Search.getIndexName(sortBy, usage='sort') if sortOrder == 'desc': params['sort_order'] = 'reverse' else: params['sort_order'] = None # If defined, add the filter among search parameters. if filterKey: filterKey = Search.getIndexName(filterKey) filterValue = Search.getSearchValue(filterKey, filterValue) params[filterKey] = filterValue # TODO This value needs to be merged with an existing one if already # in params, or, in a first step, we should avoid to display the # corresponding filter widget on the screen. if refObject: refField = refObject.getAppyType(refField) params['UID'] = getattr(refObject, refField.name).data # Use index "Allowed" if noSecurity is False if not noSecurity: params['Allowed'] = self.getAllowedValue() brains = self.getPath("/catalog")(**params) if brainsOnly: # Return brains only. if not maxResults: return brains else: return brains[:maxResults] if not maxResults: if refField: maxResults = refField.maxPerPage else: maxResults = self.appy().numberOfResultsPerPage elif maxResults == 'NO_LIMIT': maxResults = None res = SomeObjects(brains, maxResults, startNumber, noSecurity=noSecurity) res.brainsToObjects() # In some cases (p_remember=True), we need to keep some information # about the query results in the current user's session, allowing him # to navigate within elements without re-triggering the query every # time a page for an element is consulted. if remember: if not searchName: # It is the global search for all objects pf p_className searchName = className uids = {} i = -1 for obj in res.objects: i += 1 uids[startNumber + i] = obj.UID() self.REQUEST.SESSION['search_%s' % searchName] = uids return res.__dict__