def build_query_fragment(self, field, filter_type, value): from haystack import connections query_frag = "" if not hasattr(value, "input_type_name"): # Handle when we've got a ``ValuesListQuerySet``... if hasattr(value, "values_list"): value = list(value) if filter_type in ["regex", "iregex"]: value = RegExp(value) elif filter_type in ["fuzzy"]: value = PythonData(value) elif self.is_function(value): value = Exact(value) elif isinstance(value, six.string_types): # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: value = PythonData(value) # Prepare the query using the InputType. prepared_value = value.prepare(self) if not isinstance(prepared_value, (set, list, tuple)): # Then convert whatever we get back to what pysolr wants if needed. prepared_value = self.backend.conn._from_python(prepared_value) if isinstance(prepared_value, str): words_in_value = len(prepared_value.split()) words_in_value = 0 if words_in_value == 1 else 1 # 'content' is a special reserved word, much like 'pk' in # Django's ORM layer. It indicates 'no special field'. if field == "content": index_fieldname = "" else: index_fieldname = "%s" % connections[self._using].get_unified_index().get_index_fieldname(field) filter_types = { "content": ["%s", '"%s"'], "contains": ["*%s*", '"*%s*"'], "endswith": ["*%s"], "startswith": ["%s*"], "exact": ["%s", '"%s"'], "gt": ["{%s TO *}"], "gte": ["[%s TO *]"], "lt": ["{* TO %s}"], "lte": ["[* TO %s]"], "fuzzy": ["%s~", '"%s"~'], "regex": ["/%s/"], "iregex": ["/%s/"], "isnull": ["-%s:[* TO *]", "%s:[* TO *]"], } if value.post_process is False: query_frag = prepared_value else: if filter_type in ["content", "exact", "contains", "startswith", "endswith", "fuzzy", "regex", "iregex", "isnull"]: if value.input_type_name == "exact": query_frag = prepared_value elif filter_type == "fuzzy": # Check if we are using phrases (words between ") # match = re.compile('^([^\\\~]*)\\\~?(\d*)?$').match(prepared_value) match = re.compile("^([^\~]*)\~?(\d*)?$").match(prepared_value) if match: # If the user provided the ~[\d] part of the fuzzy if match.group(2): if not words_in_value: query_frag = "%s~%s" % match.groups() else: query_frag = '"%s"~%s' % match.groups() query_frag = ( filter_types[filter_type][words_in_value] % prepared_value if not len(query_frag) else query_frag ) elif filter_type in ["startswith", "endswith"]: if words_in_value == 0: query_frag = filter_types[filter_type][words_in_value] % prepared_value else: if filter_type in ["startswith"]: query_frag = " AND ".join(prepared_value.split()) + "*" else: query_frag = "*" + " AND ".join(prepared_value.split()) elif filter_type == "isnull": if prepared_value == "true": return filter_types[filter_type][0] % index_fieldname elif prepared_value == "false": return filter_types[filter_type][1] % index_fieldname else: query_frag = filter_types[filter_type][words_in_value] % prepared_value elif filter_type == "in": in_options = [] if not prepared_value: query_frag = "(!*:*)" else: for possible_value in prepared_value: in_options.append('"%s"' % self.backend.conn._from_python(possible_value)) query_frag = "(%s)" % " OR ".join(in_options) elif filter_type == "range": start = self.backend.conn._from_python(prepared_value[0]) end = self.backend.conn._from_python(prepared_value[1]) query_frag = '["%s" TO "%s"]' % (start, end) elif filter_type == "exact": if value.input_type_name == "exact": query_frag = prepared_value else: prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type][words_in_value] % prepared_value else: if value.input_type_name != "exact": prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type][words_in_value] % prepared_value if len(query_frag) and not isinstance(value, Raw) and filter_type not in ["regex", "iregex"]: if not query_frag.startswith("(") and not query_frag.endswith(")"): query_frag = "(%s)" % query_frag elif isinstance(value, Raw): return query_frag # Check if the field is making a reference to a Tuple/UDF object # Obtain the list of searchable fields available at the Index # class associated to the model searchable_fields = connections[self._using].get_unified_index().all_searchfields() # Get the model attribute that is connected to the current # index search field. # If the param was for a dict entry, the index_fieldname won't be in the list of # searcheable fields, as the field is a combination of the fieldname plus the key if index_fieldname in searchable_fields: model_attr = searchable_fields[index_fieldname].model_attr if model_attr and "." in model_attr: return "{{!tuple v='{field}:{value}'}}".format(field=model_attr, value=query_frag) else: return "%s:%s" % (index_fieldname, query_frag) else: return "%s:%s" % (index_fieldname, query_frag)
def build_query_fragment(self, field, filter_type, value): from haystack import connections query_frag = '' if not hasattr(value, 'input_type_name'): # Handle when we've got a ``ValuesListQuerySet``... if hasattr(value, 'values_list'): value = list(value) if isinstance(value, six.string_types): # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: value = PythonData(value) # Prepare the query using the InputType. prepared_value = value.prepare(self) if not isinstance(prepared_value, (set, list, tuple)): # Then convert whatever we get back to what pysolr wants if needed. prepared_value = self.backend._from_python(prepared_value) # 'content' is a special reserved word, much like 'pk' in # Django's ORM layer. It indicates 'no special field'. if field == 'content': index_fieldname = '' else: index_fieldname = u'%s:' % connections[ self._using].get_unified_index().get_index_fieldname(field) filter_types = { 'content': u'%s', 'contains': u'*%s*', 'endswith': u'*%s', 'startswith': u'%s*', 'exact': u'%s', 'gt': u'{%s TO *}', 'gte': u'[%s TO *]', 'lt': u'{* TO %s}', 'lte': u'[* TO %s]', 'fuzzy': u'%s~', } if value.post_process is False: query_frag = prepared_value else: if filter_type in [ 'content', 'contains', 'startswith', 'endswith', 'fuzzy' ]: if value.input_type_name == 'exact': query_frag = prepared_value else: # Iterate over terms & incorportate the converted form of each into the query. terms = [] if isinstance(prepared_value, six.string_types): for possible_value in prepared_value.split(' '): terms.append( filter_types[filter_type] % self.backend._from_python(possible_value)) else: terms.append(filter_types[filter_type] % self.backend._from_python(prepared_value)) if len(terms) == 1: query_frag = terms[0] else: query_frag = u"(%s)" % " AND ".join(terms) elif filter_type == 'in': in_options = [] if not prepared_value: query_frag = u'(!*:*)' else: for possible_value in prepared_value: in_options.append( u'"%s"' % self.backend._from_python(possible_value)) query_frag = u"(%s)" % " OR ".join(in_options) elif filter_type == 'range': start = self.backend._from_python(prepared_value[0]) end = self.backend._from_python(prepared_value[1]) query_frag = u'["%s" TO "%s"]' % (start, end) elif filter_type == 'exact': if value.input_type_name == 'exact': query_frag = prepared_value else: prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value else: if value.input_type_name != 'exact': prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value if len(query_frag) and not isinstance(value, Raw): if not query_frag.startswith('(') and not query_frag.endswith(')'): query_frag = "(%s)" % query_frag return u"%s%s" % (index_fieldname, query_frag)
def build_query_fragment(self, field, filter_type, value): from haystack import connections query_frag = '' is_datetime = False if not hasattr(value, 'input_type_name'): # Handle when we've got a ``ValuesListQuerySet``... if hasattr(value, 'values_list'): value = list(value) if hasattr(value, 'strftime'): is_datetime = True if isinstance(value, basestring) and value != ' ': # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: value = PythonData(value) # Prepare the query using the InputType. prepared_value = value.prepare(self) if not isinstance(prepared_value, (set, list, tuple)): # Then convert whatever we get back to what pysolr wants if needed. prepared_value = self.backend._from_python(prepared_value) # 'content' is a special reserved word, much like 'pk' in # Django's ORM layer. It indicates 'no special field'. if field == 'content': index_fieldname = '' else: index_fieldname = u'%s:' % connections[ self._using].get_unified_index().get_index_fieldname(field) filter_types = { 'contains': '%s', 'startswith': "%s*", 'exact': '%s', 'gt': "{%s to}", 'gte': "[%s to]", 'lt': "{to %s}", 'lte': "[to %s]", } if value.post_process is False: query_frag = prepared_value else: if filter_type in ['contains', 'startswith']: if value.input_type_name == 'exact': query_frag = prepared_value else: # Iterate over terms & incorportate the converted form of each into the query. terms = [] if isinstance(prepared_value, basestring): possible_values = prepared_value.split(' ') else: if is_datetime is True: prepared_value = self._convert_datetime( prepared_value) possible_values = [prepared_value] for possible_value in possible_values: terms.append(filter_types[filter_type] % self.backend._from_python(possible_value)) if len(terms) == 1: query_frag = terms[0] else: query_frag = u"(%s)" % " AND ".join(terms) elif filter_type == 'in': in_options = [] for possible_value in prepared_value: is_datetime = False if hasattr(possible_value, 'strftime'): is_datetime = True pv = self.backend._from_python(possible_value) if is_datetime is True: pv = self._convert_datetime(pv) in_options.append('"%s"' % pv) query_frag = "(%s)" % " OR ".join(in_options) elif filter_type == 'range': start = self.backend._from_python(prepared_value[0]) end = self.backend._from_python(prepared_value[1]) if hasattr(prepared_value[0], 'strftime'): start = self._convert_datetime(start) if hasattr(prepared_value[1], 'strftime'): end = self._convert_datetime(end) query_frag = u"[%s to %s]" % (start, end) elif filter_type == 'exact': if value.input_type_name == 'exact': query_frag = prepared_value else: prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value else: if is_datetime is True: prepared_value = self._convert_datetime(prepared_value) query_frag = filter_types[filter_type] % prepared_value return u"%s%s" % (index_fieldname, query_frag)
def build_query_fragment(self, field, filter_type, value): from haystack import connections query_frag = "" is_datetime = False if not hasattr(value, "input_type_name"): # Handle when we've got a ``ValuesListQuerySet``... if hasattr(value, "values_list"): value = list(value) if hasattr(value, "strftime"): is_datetime = True if isinstance(value, str) and value != " ": # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: value = PythonData(value) # Prepare the query using the InputType. prepared_value = value.prepare(self) if not isinstance(prepared_value, (set, list, tuple)): # Then convert whatever we get back to what pysolr wants if needed. prepared_value = self.backend._from_python(prepared_value) # 'content' is a special reserved word, much like 'pk' in # Django's ORM layer. It indicates 'no special field'. if field == "content": index_fieldname = "" else: index_fieldname = "%s:" % connections[ self._using].get_unified_index().get_index_fieldname(field) filter_types = { "content": "%s", "contains": "*%s*", "endswith": "*%s", "startswith": "%s*", "exact": "%s", "gt": "{%s to}", "gte": "[%s to]", "lt": "{to %s}", "lte": "[to %s]", "fuzzy": "%s~{}/%d".format(FUZZY_WHOOSH_MAX_EDITS), } if value.post_process is False: query_frag = prepared_value else: if filter_type in [ "content", "contains", "startswith", "endswith", "fuzzy", ]: if value.input_type_name == "exact": query_frag = prepared_value else: # Iterate over terms & incorportate the converted form of each into the query. terms = [] if isinstance(prepared_value, str): possible_values = prepared_value.split(" ") else: if is_datetime is True: prepared_value = self._convert_datetime( prepared_value) possible_values = [prepared_value] for possible_value in possible_values: possible_value_str = self.backend._from_python( possible_value) if filter_type == "fuzzy": terms.append(filter_types[filter_type] % ( possible_value_str, min(FUZZY_WHOOSH_MIN_PREFIX, len(possible_value_str)), )) else: terms.append(filter_types[filter_type] % possible_value_str) if len(terms) == 1: query_frag = terms[0] else: query_frag = "(%s)" % " AND ".join(terms) elif filter_type == "in": in_options = [] for possible_value in prepared_value: is_datetime = False if hasattr(possible_value, "strftime"): is_datetime = True pv = self.backend._from_python(possible_value) if is_datetime is True: pv = self._convert_datetime(pv) if isinstance(pv, str) and not is_datetime: in_options.append('"%s"' % pv) else: in_options.append("%s" % pv) query_frag = "(%s)" % " OR ".join(in_options) elif filter_type == "range": start = self.backend._from_python(prepared_value[0]) end = self.backend._from_python(prepared_value[1]) if hasattr(prepared_value[0], "strftime"): start = self._convert_datetime(start) if hasattr(prepared_value[1], "strftime"): end = self._convert_datetime(end) query_frag = "[%s to %s]" % (start, end) elif filter_type == "exact": if value.input_type_name == "exact": query_frag = prepared_value else: prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value else: if is_datetime is True: prepared_value = self._convert_datetime(prepared_value) query_frag = filter_types[filter_type] % prepared_value if len(query_frag) and not isinstance(value, Raw): if not query_frag.startswith("(") and not query_frag.endswith(")"): query_frag = "(%s)" % query_frag return "%s%s" % (index_fieldname, query_frag)
def _query_results(query, person): """ Actually build the query results for this person. Make sure any result.content_type values are reflected in RESULT_TYPE_DISPLAY for display to the user. """ if len(query) < 2: return [] query = query.replace( '@sfu.ca', '') # hack to make email addresses searchable as userids query = Clean(query) # offerings person was a member of (coredata.CourseOffering) if person: members = Member.objects.filter(person=person).exclude( role='DROP').select_related('offering') offering_slugs = set(m.offering.slug for m in members) offering_results = SearchQuerySet().models(CourseOffering).filter( text=query) # offerings that match the query offering_results = offering_results.filter( slug__in=offering_slugs) # ... and this person was in else: members = [] offering_results = [] # pages this person can view (pages.Page) page_acl = set(['ALL']) for m in members: # builds a set of offering_slug+"_"+acl_value strings, which will match the permission_key field in the index member_acl = set("%s_%s" % (m.offering.slug, acl) for acl in ACL_ROLES[m.role] if acl != 'ALL') page_acl |= member_acl page_results = SearchQuerySet().models(Page).filter( text=query) # pages that match the query page_results = page_results.filter( permission_key__in=page_acl) # ... and are visible to this user # discussion this person can view (discussion.DiscussionTopic) if person: discuss_results = SearchQuerySet().models(DiscussionTopic).filter( text=query) # discussions that match the query discuss_results = discuss_results.filter( slug__in=offering_slugs) # ... and this person was in else: discuss_results = [] # students taught by instructor (coredata.Member) instr_members = Member.objects.filter(person=person, role__in=['INST','TA']).exclude(offering__component='CAN') \ .select_related('offering') if person and instr_members: offering_slugs = set(m.offering.slug for m in instr_members) member_results = SearchQuerySet().models(Member).filter( text=query) # members that match the query member_results = member_results.filter( offering_slug__in=offering_slugs ) # ... and this person was the instructor for member_results = member_results.load_all() else: member_results = [] # combine and limit to best results results = itertools.chain( offering_results[:MAX_RESULTS], page_results[:MAX_RESULTS], member_results[:MAX_RESULTS], discuss_results[:MAX_RESULTS], ) results = (r for r in results if r is not None) results = list(results) results.sort(key=lambda result: -result.score) results = results[: MAX_RESULTS] # (list before this could be n*MAX_RESULTS long) return results
def get_queryset(self): queryset = SearchQuerySet() if hasattr(self.request, 'accepted_media_type') and re.match( KML_REGEXP, self.request.accepted_media_type): queryset = queryset.models(Unit) self.only_fields['unit'].extend(['street_address', 'www']) input_val = self.request.query_params.get('input', '').strip() q_val = self.request.query_params.get('q', '').strip() if not input_val and not q_val: raise ParseError( "Supply search terms with 'q=' or autocomplete entry with 'input='" ) if input_val and q_val: raise ParseError("Supply either 'q' or 'input', not both") if input_val: queryset = queryset.filter( SQ(autosuggest=input_val) | SQ(autosuggest_extra_searchwords=input_val) | SQ(autosuggest_exact__exact=input_val) | SQ(SQ(number=input_val) & SQ(autosuggest=input_val))) else: queryset = (queryset.filter(name=Clean(q_val)).filter_or( text=Clean(q_val)).filter_or( extra_searchwords=q_val).filter_or(address=q_val)) IS_NOT_UNIT_SQ = (SQ(django_ct='services.service') | SQ(django_ct='services.servicenode') | SQ(django_ct='munigeo.address')) if 'municipality' in self.request.query_params: val = self.request.query_params['municipality'].lower().strip() if len(val) > 0: municipalities = val.split(',') muni_sq = SQ(municipality=municipalities.pop().strip()) for m in municipalities: muni_sq |= SQ(municipality=m) queryset = queryset.filter(SQ(muni_sq | IS_NOT_UNIT_SQ)) if 'city_as_department' in self.request.query_params: val = self.request.query_params['city_as_department'].lower( ).strip() if len(val) > 0: deps_uuid = val.split(',') # forming municipality search query deps = Department.objects.filter( uuid__in=deps_uuid).select_related('municipality') munis = [d.municipality.name for d in deps] muni_sq = SQ(municipality=munis.pop()) for m in munis: muni_sq |= SQ(municipality=m) # forming root_deparment search query dep_sq = SQ(root_department=deps_uuid.pop().strip()) for d in deps_uuid: dep_sq |= SQ(root_department=d) # updating queryset queryset = queryset.filter( SQ(muni_sq | dep_sq | IS_NOT_UNIT_SQ)) service = self.request.query_params.get('service') if service: services = service.split(',') queryset = queryset.filter(django_ct='services.unit').filter( services__in=services) # Only units marked public should be returned. For other types, # public is always True. queryset = queryset.filter(public='true') models = set() types = self.request.query_params.get('type', '').split(',') for t in types: if t == 'service_node': models.add(ServiceNode) elif t == 'service': models.add(Service) elif t == 'unit': models.add(Unit) elif t == 'address': models.add(Address) elif t == 'administrative_division': models.add(AdministrativeDivision) if self._is_kml_media_type_request(): queryset = queryset.models(Unit) elif len(models) > 0: queryset = queryset.models(*list(models)) else: # Hide the to-be-deprecated servicenode from default types queryset = queryset.models(Service, Unit, Address, AdministrativeDivision) return queryset
def build_query_fragment(self, field, filter_type, value): from haystack import connections query_frag = "" if not hasattr(value, "input_type_name"): # Handle when we've got a ``ValuesListQuerySet``... if hasattr(value, "values_list"): value = list(value) if isinstance(value, six.string_types): # It's not an ``InputType``. Assume ``Clean``. value = Clean(value) else: value = PythonData(value) # Prepare the query using the InputType. prepared_value = value.prepare(self) if not isinstance(prepared_value, (set, list, tuple)): # Then convert whatever we get back to what pysolr wants if needed. prepared_value = self.backend.conn._from_python(prepared_value) # 'content' is a special reserved word, much like 'pk' in # Django's ORM layer. It indicates 'no special field'. if field == "content": index_fieldname = "" else: index_fieldname = "%s:" % connections[ self._using ].get_unified_index().get_index_fieldname(field) filter_types = { "content": "%s", "contains": "*%s*", "endswith": "*%s", "startswith": "%s*", "exact": "%s", "gt": "{%s TO *}", "gte": "[%s TO *]", "lt": "{* TO %s}", "lte": "[* TO %s]", "fuzzy": "%s~", } if value.post_process is False: query_frag = prepared_value else: if filter_type in [ "content", "contains", "startswith", "endswith", "fuzzy", ]: if value.input_type_name == "exact": query_frag = prepared_value else: # Iterate over terms & incorportate the converted form of each into the query. terms = [] for possible_value in prepared_value.split(" "): terms.append( filter_types[filter_type] % self.backend.conn._from_python(possible_value) ) if len(terms) == 1: query_frag = terms[0] else: query_frag = "(%s)" % " AND ".join(terms) elif filter_type == "in": in_options = [] if not prepared_value: query_frag = "(!*:*)" else: for possible_value in prepared_value: in_options.append( '"%s"' % self.backend.conn._from_python(possible_value) ) query_frag = "(%s)" % " OR ".join(in_options) elif filter_type == "range": start = self.backend.conn._from_python(prepared_value[0]) end = self.backend.conn._from_python(prepared_value[1]) query_frag = '["%s" TO "%s"]' % (start, end) elif filter_type == "exact": if value.input_type_name == "exact": query_frag = prepared_value else: prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value else: if value.input_type_name != "exact": prepared_value = Exact(prepared_value).prepare(self) query_frag = filter_types[filter_type] % prepared_value if len(query_frag) and not isinstance(value, Raw): if not query_frag.startswith("(") and not query_frag.endswith(")"): query_frag = "(%s)" % query_frag return "%s%s" % (index_fieldname, query_frag)
def reduce_query(self, keywords): query = reduce(self.join_search_queries, keywords) if not isinstance(query, SQ): return SQ(contains=Clean(query)) return query
def join_search_queries(self, left, right): left = left if isinstance(left, SQ) else SQ(contains=Clean(left)) right = right if isinstance(right, SQ) else SQ(contains=Clean(right)) return left & right
def ask_search(request, language='en', as_json=False): if 'selected_facets' in request.GET: return redirect_ask_search(request, language=language) language_map = { 'en': { 'slug': 'ask-cfpb-search-results', 'query': SearchQuerySet().models(EnglishAnswerProxy) }, 'es': { 'slug': 'respuestas', 'query': SearchQuerySet().models(SpanishAnswerProxy) } } _map = language_map[language] sqs = _map['query'] clean_query = Clean(request.GET.get('q', '')) clean_qstring = clean_query.query_string.strip() qstring = clean_qstring query_sqs = sqs.filter(content=clean_query) results_page = get_object_or_404(AnswerResultsPage, language=language, slug=_map['slug']) # If there's no query string, don't search if not qstring: results_page.query = '' results_page.result_query = '' return results_page.serve(request) # If we have no results from our query, let's try to suggest a better one suggestion = sqs.spelling_suggestion(qstring) if suggestion == qstring: suggestion = None elif (query_sqs.count() == 0 and request.GET.get('correct', '1') == '1' and flag_enabled('ASK_SEARCH_TYPOS', request=request)): query_sqs = sqs.filter(content=suggestion) qstring, suggestion = suggestion, qstring if as_json: results = { 'query': clean_qstring, 'result_query': qstring, 'suggestion': suggestion, 'results': [{ 'question': result.autocomplete, 'url': result.url, 'text': result.text } for result in query_sqs] } json_results = json.dumps(results) return HttpResponse(json_results, content_type='application/json') else: results_page.query = clean_qstring results_page.result_query = qstring results_page.suggestion = suggestion results_page.answers = [] for result in query_sqs: results_page.answers.append( (result.url, result.autocomplete, result.text)) return results_page.serve(request)
def search(self): if not self.is_valid(): return self.no_query_found() sqs = self.searchqueryset for facet in self.selected_facets: if ":" not in facet: continue field, value = facet.split(":", 1) if value: sqs = sqs.narrow(u'%s:%s' % (field, value)) #print(self.cleaned_data) if self.cleaned_data['q']: sqs = sqs.auto_query(self.cleaned_data['q']) if self.cleaned_data['title']: sqs = sqs.filter(title=AutoQuery(self.cleaned_data['title'])) if self.cleaned_data['license']: sqs = sqs.filter(license=AutoQuery(self.cleaned_data['license'])) if self.cleaned_data['funded_by']: sqs = sqs.filter( funded_by=AutoQuery(self.cleaned_data['funded_by'])) if self.cleaned_data['domain']: sqs = sqs.filter( web_domains__in=AutoQuery(self.cleaned_data['domain'])) if self.cleaned_data['exclude']: sqs = sqs.exclude(content=Clean(self.cleaned_data['exclude'])) if self.cleaned_data['concept']: #expand concept selection as wide as we can m_concepts = self.cleaned_data['concept'].search_matched( ).alternative_children().get_descendants(include_self=True) sqs = sqs.filter(concepts__in=as_ids(m_concepts.distinct())) #TODO use keywords to search meta data (dataset's own reported keywords)? if self.cleaned_data['publisher']: #TODO expand publisher selection to include subpublishers m_publishers = self.cleaned_data['publisher'] sqs = sqs.filter(publisher__in=as_ids(m_publishers)) if self.cleaned_data['spatial_entity']: sqs = sqs.filter( spatial_entity__in=as_ids(self.cleaned_data['spatial_entity'])) if self.cleaned_data['location_lng'] and self.cleaned_data[ 'location_lat']: point = Point(self.cleaned_data['location_lat'], self.cleaned_data['location_lng']) sqs = sqs.dwithin('location', point, D(mi=2)) if self.cleaned_data['language']: sqs = sqs.filter(language=self.cleaned_data['language']) if self.cleaned_data['access_level']: sqs = sqs.filter( access_level__in=self.cleaned_data['access_level']) if self.cleaned_data['sort_by']: sqs = sqs.order_by(self.cleaned_data['sort_by']) if self.cleaned_data['result_types']: models = map(model_choice_to_model, self.cleaned_data['result_types']) sqs = sqs.models(*models) else: sqs = sqs.models(Story, CatalogRecord) return sqs
def has_permission(self, request, view): q = request.QUERY_PARAMS.get('q') query_length = getattr(settings, "SEARCH_QUERY_LENGTH", 3) if not (q and len(Clean(q).query_string) > query_length): return False return True