def search(request): if request.method == 'GET': query = request.GET.get('q') if len(query) >= 3: from haystack.query import SearchQuerySet response = SearchQuerySet().autocomplete(name_auto=query) if response.count() > 0: from django.contrib.auth.models import User if response.count() >1: return render_to_response( 'search.html', { 'result_characters': response.models(Character), 'result_users': response.models(User), 'results': response }, context_instance=RequestContext(request) ) else: if response.models(User): return HttpResponseRedirect('/accounts/profile/%s/' % response[0].object.id) else: return HttpResponseRedirect('/character/%s/' % response[0].object.character_id) else: return render_to_response( 'search.html', { 'results': None }, context_instance=RequestContext(request) ) else: raise Http404() else: raise Http404()
def test_models(self): # Stow. old_unified_index = connections["default"]._index ui = UnifiedIndex() bmmsi = BasicMockModelSearchIndex() bammsi = BasicAnotherMockModelSearchIndex() ui.build(indexes=[bmmsi, bammsi]) connections["default"]._index = ui msqs = SearchQuerySet() sqs = msqs.all() self.assertTrue(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 0) sqs = msqs.models(MockModel) self.assertTrue(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 1) sqs = msqs.models(MockModel, AnotherMockModel) self.assertTrue(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 2) # This will produce a warning. ui.build(indexes=[bmmsi]) sqs = msqs.models(AnotherMockModel) self.assertTrue(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 1)
class LiveWhooshMultiSearchQuerySetTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(LiveWhooshMultiSearchQuerySetTestCase, self).setUp() # Stow. temp_path = os.path.join('tmp', 'test_whoosh_query') self.old_whoosh_path = getattr(settings, 'HAYSTACK_WHOOSH_PATH', temp_path) settings.HAYSTACK_WHOOSH_PATH = temp_path self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.smmi = WhooshMockSearchIndex(MockModel, backend=self.sb) self.sammi = WhooshAnotherMockSearchIndex(AnotherMockModel, backend=self.sb) self.site.register(MockModel, WhooshMockSearchIndex) self.site.register(AnotherMockModel, WhooshAnotherMockSearchIndex) # Stow. import haystack self.old_debug = settings.DEBUG settings.DEBUG = True self.old_site = haystack.site haystack.site = self.site self.sb.setup() self.raw_whoosh = self.sb.index self.parser = QueryParser(self.sb.content_field_name, schema=self.sb.schema) self.sb.delete_index() self.sq = SearchQuery(backend=self.sb) self.sqs = SearchQuerySet(site=self.site) self.smmi.update() self.sammi.update() def tearDown(self): if os.path.exists(settings.HAYSTACK_WHOOSH_PATH): shutil.rmtree(settings.HAYSTACK_WHOOSH_PATH) settings.HAYSTACK_WHOOSH_PATH = self.old_whoosh_path import haystack haystack.site = self.old_site settings.DEBUG = self.old_debug super(LiveWhooshMultiSearchQuerySetTestCase, self).tearDown() def test_searchquerysets_with_models(self): sqs = self.sqs.all() self.assertEqual(sqs.query.build_query(), u'*') self.assertEqual(len(sqs), 25) sqs = self.sqs.models(MockModel) self.assertEqual(sqs.query.build_query(), u'django_ct:core.mockmodel') self.assertEqual(len(sqs), 23) sqs = self.sqs.models(AnotherMockModel) self.assertEqual(sqs.query.build_query(), u'django_ct:core.anothermockmodel') self.assertEqual(len(sqs), 2)
def search(request): """ This view is used for search; it sends the keyword to quey on to the haystcks' search. If the user did not provide a keyword to search on, it searches an empty query. """ try: q = request.POST['q'] except: q = '' if q == '': results = SearchQuerySet().all() else: results = SearchQuerySet().filter(content=AutoQuery(q)) results = results.filter_or(tags=AutoQuery(q)) results = results.filter_or(title=AutoQuery(q)) results = results.filter_or(location=AutoQuery(q)) people = results.models(UserProfile) tasks = results.models(Task) return render_to_response( 'search/results.html', { 'tresults': tasks, 'presults': people, 'keyword': q, 'peopleCount': len(people), 'taskCount': len(tasks) }, RequestContext(request))
def search(request): """The search page.""" query = request.GET.get("q") if not query: return redirect("core:home") # Search for Issue and Tags matching the query. results = SearchQuerySet().auto_query(query).load_all() issues = [result.object for result in results.models(Issue)] tags = [result.object for result in results.models(Tag)] # Extract commons tags that may not be in the search results. Remove # duplicates as this is shown below the results (but preserve ordering). related_tags = Issue.common_tags(issues) related_tags = [tag for tag in related_tags if tag not in tags] if len(results) == 0: username = "******" if not request.user.is_anonymous(): username = request.user.get_full_name() logging.getLogger("email").info("Failed Search", extra={"body": "%s searched for \"%s\", but no results were found." % ( username, query ) }) return { "issues": issues, "page": Paginator(issues, 25).page(request.GET.get("page", 1)), "query": query, "tags": (tags + related_tags)[:20] }
def get_results(self, query, partner): sqs = SearchQuerySet() clean_query = sqs.query.clean(query) course_runs = sqs.models(CourseRun).filter( SQ(title_autocomplete=clean_query) | SQ(course_key=clean_query) | SQ(authoring_organizations_autocomplete=clean_query) ) course_runs = course_runs.filter(published=True).exclude(hidden=True).filter(partner=partner.short_code) # Get first three results after deduplicating by course key. seen_course_keys, course_run_list = set(), [] for course_run in course_runs: course_key = course_run.course_key if course_key in seen_course_keys: continue seen_course_keys.add(course_key) course_run_list.append(course_run) if len(course_run_list) == self.RESULT_COUNT: break programs = sqs.models(Program).filter( SQ(title_autocomplete=clean_query) | SQ(authoring_organizations_autocomplete=clean_query) ) programs = programs.filter(status=ProgramStatus.Active).exclude(hidden=True).filter(partner=partner.short_code) programs = programs[:self.RESULT_COUNT] return course_run_list, programs
def search(self, request, collection, filter_parameters, order_parameters): parameters = ' | '.join(collection.parameters.split(',')).strip(' |') objects = SearchQuerySet().filter(content=parameters) if hasattr(settings, "COLLECTIONS_HAYSTACK_MODELS"): haystack_models = settings.COLLECTIONS_HAYSTACK_MODELS #if we're a string pull out the function if isinstance(haystack_models, str): mod_name, func_name = get_mod_func(haystack_models) haystack_models = getattr(import_module(mod_name), func_name) #if we're a function pull out the models if callable(haystack_models): haystack_models = haystack_models(request) model_list = [] for haystack_model in haystack_models: app_model = haystack_model.split('.') model_list.append(get_model(*app_model)) objects.models(*model_list) if isinstance(order_parameters, list): objects = objects.order_by(*order_parameters) if isinstance(filter_parameters, dict): objects = objects.filter(**filter_parameters) return objects
def test_models(self): # Stow. old_unified_index = connections['default']._index ui = UnifiedIndex() bmmsi = BasicMockModelSearchIndex() bammsi = BasicAnotherMockModelSearchIndex() ui.build(indexes=[bmmsi, bammsi]) connections['default']._index = ui msqs = SearchQuerySet() sqs = msqs.all() self.assertTrue(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 0) sqs = msqs.models(MockModel) self.assertTrue(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 1) sqs = msqs.models(MockModel, AnotherMockModel) self.assertTrue(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 2) # This will produce a warning. ui.build(indexes=[bmmsi]) sqs = msqs.models(AnotherMockModel) self.assertTrue(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 1)
def search(request): App = apps.get_model('apps', 'App') Tag = apps.get_model('apps', 'Tag') top_tags, not_top_tags = findTags() query = request.GET.get('q', '') sqs_app = SearchQuerySet() sqs_tag = SearchQuerySet() sqs_app = sqs_app.models(App) sqs_tag = sqs_tag.models(Tag) sqs_app = sqs_app.filter(title__contains=query).filter( abstract__contains=query).filter(description__contains=query) sqs_tag = sqs_tag.filter(title__contains=query) app = set() tag = set() for item in sqs_app: app.add(item.object) for item in sqs_tag: tag.add(item.object) context = { 'top_tags': top_tags, 'not_top_tags': not_top_tags, 'sqs_app': app, 'sqs_tag': tag, } return render(request, 'search.html', context)
class LiveSolrMoreLikeThisTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(LiveSolrMoreLikeThisTestCase, self).setUp() # Wipe it clean. clear_solr_index() # With the models registered, you get the proper bits. import haystack from haystack.sites import SearchSite # Stow. self.old_site = haystack.site test_site = SearchSite() test_site.register(MockModel, SolrMockModelSearchIndex) test_site.register(AnotherMockModel, SolrAnotherMockModelSearchIndex) haystack.site = test_site self.sqs = SearchQuerySet() test_site.get_index(MockModel).update() test_site.get_index(AnotherMockModel).update() def tearDown(self): # Restore. import haystack haystack.site = self.old_site super(LiveSolrMoreLikeThisTestCase, self).tearDown() def test_more_like_this(self): mlt = self.sqs.more_like_this(MockModel.objects.get(pk=1)) self.assertEqual(mlt.count(), 24) self.assertEqual([result.pk for result in mlt], ['6', '14', '4', '10', '22', '5', '3', '12', '2', '23', '18', '19', '13', '7', '15', '21', '9', '1', '2', '20', '16', '17', '8', '11']) self.assertEqual(len([result.pk for result in mlt]), 24) alt_mlt = self.sqs.filter(name='daniel3').more_like_this(MockModel.objects.get(pk=3)) self.assertEqual(alt_mlt.count(), 10) self.assertEqual([result.pk for result in alt_mlt], ['23', '13', '17', '16', '22', '19', '4', '10', '1', '2']) self.assertEqual(len([result.pk for result in alt_mlt]), 10) alt_mlt_with_models = self.sqs.models(MockModel).more_like_this(MockModel.objects.get(pk=1)) self.assertEqual(alt_mlt_with_models.count(), 22) self.assertEqual([result.pk for result in alt_mlt_with_models], ['6', '14', '4', '10', '22', '5', '3', '12', '2', '23', '18', '19', '13', '7', '15', '21', '9', '20', '16', '17', '8', '11']) self.assertEqual(len([result.pk for result in alt_mlt_with_models]), 22) if hasattr(MockModel.objects, 'defer'): # Make sure MLT works with deferred bits. mi = MockModel.objects.defer('foo').get(pk=1) self.assertEqual(mi._deferred, True) deferred = self.sqs.models(MockModel).more_like_this(mi) self.assertEqual(deferred.count(), 0) self.assertEqual([result.pk for result in deferred], []) self.assertEqual(len([result.pk for result in deferred]), 0) # Ensure that swapping the ``result_class`` works. self.assertTrue(isinstance(self.sqs.result_class(MockSearchResult).more_like_this(MockModel.objects.get(pk=1))[0], MockSearchResult))
class LiveWhooshMoreLikeThisTestCase(WhooshTestCase): fixtures = ['bulk_data.json'] def setUp(self): super(LiveWhooshMoreLikeThisTestCase, self).setUp() # Stow. self.old_ui = connections['whoosh'].get_unified_index() self.ui = UnifiedIndex() self.wmmi = WhooshMockSearchIndex() self.wamsi = WhooshAnotherMockSearchIndex() self.ui.build(indexes=[self.wmmi, self.wamsi]) self.sb = connections['whoosh'].get_backend() connections['whoosh']._index = self.ui self.sb.setup() self.raw_whoosh = self.sb.index self.parser = QueryParser(self.sb.content_field_name, schema=self.sb.schema) self.sb.delete_index() self.wmmi.update() self.wamsi.update() self.sqs = SearchQuerySet('whoosh') def tearDown(self): connections['whoosh']._index = self.old_ui super(LiveWhooshMoreLikeThisTestCase, self).tearDown() # We expect failure here because, despite not changing the code, Whoosh # 2.5.1 returns incorrect counts/results. Huzzah. @unittest.expectedFailure def test_more_like_this(self): mlt = self.sqs.more_like_this(MockModel.objects.get(pk=22)) self.assertEqual(mlt.count(), 22) self.assertEqual(sorted([result.pk for result in mlt]), sorted([u'9', u'8', u'7', u'6', u'5', u'4', u'3', u'2', u'1', u'21', u'20', u'19', u'18', u'17', u'16', u'15', u'14', u'13', u'12', u'11', u'10', u'23'])) self.assertEqual(len([result.pk for result in mlt]), 22) alt_mlt = self.sqs.filter(name='daniel3').more_like_this(MockModel.objects.get(pk=13)) self.assertEqual(alt_mlt.count(), 8) self.assertEqual(sorted([result.pk for result in alt_mlt]), sorted([u'4', u'3', u'22', u'19', u'17', u'16', u'10', u'23'])) self.assertEqual(len([result.pk for result in alt_mlt]), 8) alt_mlt_with_models = self.sqs.models(MockModel).more_like_this(MockModel.objects.get(pk=11)) self.assertEqual(alt_mlt_with_models.count(), 22) self.assertEqual(sorted([result.pk for result in alt_mlt_with_models]), sorted([u'9', u'8', u'7', u'6', u'5', u'4', u'3', u'2', u'1', u'22', u'21', u'20', u'19', u'18', u'17', u'16', u'15', u'14', u'13', u'12', u'10', u'23'])) self.assertEqual(len([result.pk for result in alt_mlt_with_models]), 22) if hasattr(MockModel.objects, 'defer'): # Make sure MLT works with deferred bits. mi = MockModel.objects.defer('foo').get(pk=21) self.assertEqual(mi._deferred, True) deferred = self.sqs.models(MockModel).more_like_this(mi) self.assertEqual(deferred.count(), 0) self.assertEqual([result.pk for result in deferred], []) self.assertEqual(len([result.pk for result in deferred]), 0) # Ensure that swapping the ``result_class`` works. self.assertTrue(isinstance(self.sqs.result_class(MockSearchResult).more_like_this(MockModel.objects.get(pk=21))[0], MockSearchResult))
def extra_context(self): if not self.query: return {} query = SearchQuerySet().highlight() return { 'person_results': query.models(models.Person).filter(content=AutoQuery(self.request.GET['q'])), 'organisation_results': query.models(models.Organisation).filter(content=AutoQuery(self.request.GET['q'])), }
class LiveSolrMoreLikeThisTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(LiveSolrMoreLikeThisTestCase, self).setUp() # Wipe it clean. clear_solr_index() # With the models registered, you get the proper bits. import haystack from haystack.sites import SearchSite # Stow. self.old_site = haystack.site test_site = SearchSite() test_site.register(MockModel, SolrMockModelSearchIndex) test_site.register(AnotherMockModel, SolrAnotherMockModelSearchIndex) haystack.site = test_site self.sqs = SearchQuerySet() # Force indexing of the content. for mock in MockModel.objects.all(): mock.save() # Force indexing of the content. for mock in AnotherMockModel.objects.all(): mock.save() def tearDown(self): # Restore. import haystack haystack.site = self.old_site super(LiveSolrMoreLikeThisTestCase, self).tearDown() def test_more_like_this(self): mlt = self.sqs.more_like_this(MockModel.objects.get(pk=1)) self.assertEqual(mlt.count(), 25) self.assertEqual([result.pk for result in mlt], ['6', '14', '4', '10', '22', '5', '3', '12', '2', '23', '18', '19', '13', '7', '15', '21', '9', '1', '2', '20', '16', '17', '8', '11']) alt_mlt = self.sqs.filter(name='daniel3').more_like_this(MockModel.objects.get(pk=3)) self.assertEqual(alt_mlt.count(), 11) self.assertEqual([result.pk for result in alt_mlt], ['23', '13', '17', '16', '22', '19', '4', '10', '1', '2']) alt_mlt_with_models = self.sqs.models(MockModel).more_like_this(MockModel.objects.get(pk=1)) self.assertEqual(alt_mlt_with_models.count(), 23) self.assertEqual([result.pk for result in alt_mlt_with_models], ['6', '14', '4', '10', '22', '5', '3', '12', '2', '23', '18', '19', '13', '7', '15', '21', '9', '20', '16', '17', '8', '11']) if hasattr(MockModel.objects, 'defer'): # Make sure MLT works with deferred bits. mi = MockModel.objects.defer('foo').get(pk=1) self.assertEqual(mi._deferred, True) deferred = self.sqs.models(MockModel).more_like_this(mi) self.assertEqual(alt_mlt_with_models.count(), 23) self.assertEqual([result.pk for result in alt_mlt_with_models], ['6', '14', '4', '10', '22', '5', '3', '12', '2', '23', '18', '19', '13', '7', '15', '21', '9', '20', '16', '17', '8', '11'])
def get_queryset(self): queryset = super(LinkList, self).get_queryset().order_by('-added') not_on_page = 'page' not in self.request.GET if self.has_query(): queryset = SearchQuerySet().filter(content=AutoQuery( self.request.GET['q']), ).filter_or( categories=AutoQuery(self.request.GET['q'])).filter_or( network_location=AutoQuery(self.request.GET['q'])) if self.has_favourites(): fav_pks = [l.pk for l in self.request.user.favourites.all()] if self.has_query(): queryset = queryset.models(Link).filter(key__in=fav_pks) else: queryset = queryset.filter(id__in=fav_pks).distinct() if self.has_categories(): categories_to_filter = dict(self.request.GET)['categories'] if type(categories_to_filter) == str: categories_to_filter = [categories_to_filter] if self.has_query(): queryset = queryset.models(Link).filter( categories__in=categories_to_filter) else: # At this point, the queryset should already be ordered because # of the original get_queryset call at the beginning of this # function. queryset = queryset.filter( categories__name__in=categories_to_filter).distinct() if self.external_only() or self.internal_only(): if self.has_query(): queryset = queryset.models(Link).exclude( is_external=self.internal_only()) else: # At this point, the queryset should already be ordered because # of the original get_queryset call at the beginning of this # function. queryset = queryset.exclude( is_external=self.internal_only()).distinct() if self.has_query() and not self.has_categories() and not_on_page: # At this point the queryset is a list of SearchResult objects, all # of them. So, the length is accurate. By the time it reaches # context, it won't be. st, created = SearchTerm.objects.get_or_create( query=self.request.GET.get('q')) sq = SearchQuery() sq.term = st sq.results_length = len(queryset) sq.user = self.request.user sq.save() return queryset
class LiveElasticsearchMoreLikeThisTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(LiveElasticsearchMoreLikeThisTestCase, self).setUp() # Wipe it clean. clear_elasticsearch_index() self.old_ui = connections['default'].get_unified_index() self.ui = UnifiedIndex() self.smmi = ElasticsearchMockModelSearchIndex() self.sammi = ElasticsearchAnotherMockModelSearchIndex() self.ui.build(indexes=[self.smmi, self.sammi]) connections['default']._index = self.ui self.sqs = SearchQuerySet() self.smmi.update() self.sammi.update() def tearDown(self): # Restore. connections['default']._index = self.old_ui super(LiveElasticsearchMoreLikeThisTestCase, self).tearDown() @unittest.expectedFailure def test_more_like_this(self): mlt = self.sqs.more_like_this(MockModel.objects.get(pk=1)) self.assertEqual(mlt.count(), 4) self.assertEqual([result.pk for result in mlt], [u'2', u'6', u'16', u'23']) self.assertEqual(len([result.pk for result in mlt]), 4) alt_mlt = self.sqs.filter(name='daniel3').more_like_this(MockModel.objects.get(pk=2)) self.assertEqual(alt_mlt.count(), 6) self.assertEqual([result.pk for result in alt_mlt], [u'2', u'6', u'16', u'23', u'1', u'11']) self.assertEqual(len([result.pk for result in alt_mlt]), 6) alt_mlt_with_models = self.sqs.models(MockModel).more_like_this(MockModel.objects.get(pk=1)) self.assertEqual(alt_mlt_with_models.count(), 4) self.assertEqual([result.pk for result in alt_mlt_with_models], [u'2', u'6', u'16', u'23']) self.assertEqual(len([result.pk for result in alt_mlt_with_models]), 4) if hasattr(MockModel.objects, 'defer'): # Make sure MLT works with deferred bits. mi = MockModel.objects.defer('foo').get(pk=1) self.assertEqual(mi._deferred, True) deferred = self.sqs.models(MockModel).more_like_this(mi) self.assertEqual(deferred.count(), 0) self.assertEqual([result.pk for result in deferred], []) self.assertEqual(len([result.pk for result in deferred]), 0) # Ensure that swapping the ``result_class`` works. self.assertTrue(isinstance(self.sqs.result_class(MockSearchResult).more_like_this(MockModel.objects.get(pk=1))[0], MockSearchResult))
class LiveElasticsearchMoreLikeThisTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(LiveElasticsearchMoreLikeThisTestCase, self).setUp() # Wipe it clean. clear_elasticsearch_index() self.old_ui = connections['default'].get_unified_index() self.ui = UnifiedIndex() self.smmi = ElasticsearchMockModelSearchIndex() self.sammi = ElasticsearchAnotherMockModelSearchIndex() self.ui.build(indexes=[self.smmi, self.sammi]) connections['default']._index = self.ui self.sqs = SearchQuerySet() self.smmi.update() self.sammi.update() def tearDown(self): # Restore. connections['default']._index = self.old_ui super(LiveElasticsearchMoreLikeThisTestCase, self).tearDown() @unittest.expectedFailure def test_more_like_this(self): mlt = self.sqs.more_like_this(MockModel.objects.get(pk=1)) self.assertEqual(mlt.count(), 4) self.assertEqual([result.pk for result in mlt], [u'2', u'6', u'16', u'23']) self.assertEqual(len([result.pk for result in mlt]), 4) alt_mlt = self.sqs.filter(name='daniel3').more_like_this(MockModel.objects.get(pk=2)) self.assertEqual(alt_mlt.count(), 6) self.assertEqual([result.pk for result in alt_mlt], [u'2', u'6', u'16', u'23', u'1', u'11']) self.assertEqual(len([result.pk for result in alt_mlt]), 6) alt_mlt_with_models = self.sqs.models(MockModel).more_like_this(MockModel.objects.get(pk=1)) self.assertEqual(alt_mlt_with_models.count(), 4) self.assertEqual([result.pk for result in alt_mlt_with_models], [u'2', u'6', u'16', u'23']) self.assertEqual(len([result.pk for result in alt_mlt_with_models]), 4) if hasattr(MockModel.objects, 'defer'): # Make sure MLT works with deferred bits. mi = MockModel.objects.defer('foo').get(pk=1) self.assertEqual(mi._deferred, True) deferred = self.sqs.models(MockModel).more_like_this(mi) self.assertEqual(deferred.count(), 0) self.assertEqual([result.pk for result in deferred], []) self.assertEqual(len([result.pk for result in deferred]), 0) # Ensure that swapping the ``result_class`` works. self.assertTrue(isinstance(self.sqs.result_class(MockSearchResult).more_like_this(MockModel.objects.get(pk=1))[0], MockSearchResult))
def execute_query(index, query_text): qs = SearchQuerySet().order_by('id_order') model = DEFAULT_INDEXES.get(index) if model is None: qs = qs.models(DataBagItem).narrow('data_bag:%s'%index) else: qs = qs.models(model) if query_text == '*:*': # Shortcut for all models, this could even skip haystack entirely. return qs return qs.filter(query_text)
def search(self): def sorting_by_degree(result): if result.model is Pages: return '--' try: if result.object.in_followers(user): return 1 v = result.object.get_degree_for(user) except: # this could happen # run rebuild_index v = '--' return v #res = super(SearchForm, self).search() #res = SearchQuerySet().filter(username_auto=self.cleaned_data['q']) if len(self.cleaned_data['q'].strip().split(" ")) > 1: # if query has 2 and more words in it # we can't use EdgeNgrams res = SearchQuerySet().filter(content__contains=self.cleaned_data['q']) else: res = SearchQuerySet().filter(SQ(username_auto=self.cleaned_data['q']) | SQ(email=self.cleaned_data['q']) | SQ(full_name_auto=self.cleaned_data['q'])) # ajax filter filter_val = self.data.get('filter') # filtering if filter_val == 'businesses': res = res.filter(page_type='BS') if filter_val == 'nonprofits': res = res.filter(page_type='NP') if filter_val == 'people': res = res.models(UserProfile) else: res = res.models(UserProfile, Pages) if 'account.userprofile' in self.cleaned_data['models']: user = get_current_user() for one_user in res: #if hasattr(one_user.object, 'userprofile'): if one_user.object and not isinstance(one_user.object,Tag) and not isinstance(one_user.object,Pages): #if user was not deleted if not one_user.object.check_visiblity("search",user): res = res.exclude(username=one_user.username) # if in blocked list -> exclude if one_user.object in user.get_blocked(): res = res.exclude(username=one_user.username) # Ensure the current user isn't in the results. if user != None and one_user.object == user and not isinstance(one_user.object,Pages): res = res.exclude(username=user.username) # custom ordering (by DoS) #res = sorted(res,key = lambda s : s.object.get_degree_for(user)) if filter_val in ('businesses','nonprofits'): res = sorted(res,key = lambda s: s.object.loves, reverse=True) else: res = sorted(res,key = sorting_by_degree) return res
def extra_context(self): if not self.query: return {} query = SearchQuerySet().highlight() return { 'person_results': query.models(models.Person).filter( content=AutoQuery(self.request.GET['q'])).exclude(hidden=True), 'organisation_results': query.models(models.Organisation).filter( content=AutoQuery(self.request.GET['q'])), }
def handle(self, *args, **options): sqs = SearchQuerySet() users = sqs.models(User).all().count() images = sqs.models(Image).all().count() integration = 0 for i in sqs.models(Image).all(): integration += i.integration integration = int(integration / 3600.0) gs = GlobalStat(users=users, images=images, integration=integration) gs.save()
class LiveWhooshMultiSearchQuerySetTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(LiveWhooshMultiSearchQuerySetTestCase, self).setUp() # Stow. temp_path = os.path.join('tmp', 'test_whoosh_query') self.old_whoosh_path = settings.HAYSTACK_CONNECTIONS['default']['PATH'] self.old_ui = connections['default'].get_unified_index() self.ui = UnifiedIndex() self.wmmi = WhooshMockSearchIndex() self.wamsi = WhooshAnotherMockSearchIndex() self.ui.build(indexes=[self.wmmi, self.wamsi]) self.sb = connections['default'].get_backend() connections['default']._index = self.ui self.sb.setup() self.raw_whoosh = self.sb.index self.parser = QueryParser(self.sb.content_field_name, schema=self.sb.schema) self.sb.delete_index() self.wmmi.update() self.wamsi.update() self.sqs = SearchQuerySet() def tearDown(self): if os.path.exists(settings.HAYSTACK_CONNECTIONS['default']['PATH']): shutil.rmtree(settings.HAYSTACK_CONNECTIONS['default']['PATH']) settings.HAYSTACK_CONNECTIONS['default']['PATH'] = self.old_whoosh_path connections['default']._index = self.old_ui super(LiveWhooshMultiSearchQuerySetTestCase, self).tearDown() # We expect failure here because, despite not changing the code, Whoosh # 2.5.1 returns incorrect counts/results. Huzzah. @unittest.expectedFailure def test_searchquerysets_with_models(self): sqs = self.sqs.all() self.assertEqual(sqs.query.build_query(), u'*') self.assertEqual(len(sqs), 25) sqs = self.sqs.models(MockModel) self.assertEqual(sqs.query.build_query(), u'*') self.assertEqual(len(sqs), 23) sqs = self.sqs.models(AnotherMockModel) self.assertEqual(sqs.query.build_query(), u'*') self.assertEqual(len(sqs), 2)
def global_stats(): from astrobin.models import Image, GlobalStat sqs = SearchQuerySet() users = sqs.models(User).all().count() images = sqs.models(Image).all().count() integration = 0 for i in sqs.models(Image).all(): integration += i.integration integration = int(integration / 3600.0) gs = GlobalStat(users=users, images=images, integration=integration) gs.save()
def autocomplete_search(request, q, model=None, max_results=5): q = replace(q) sqs = SearchQuerySet() if model is None: unified_index = get_haystack_unified_index() models = unified_index.get_indexed_models() models = [model for model in models if 'content_auto' in unified_index.get_index(model).fields] sqs = sqs.models(*models) else: sqs = sqs.models(model) sqs = filter_published(sqs, request) sqs = sqs.autocomplete(content_auto=q)[:max_results] return list(result_iterator(sqs))
def get_facets_for_field(field, model=None, facet_limit=None, facet_mincount=None): query = SearchQuerySet() if model is not None: if isinstance(model, (tuple, list)): query = query.models(*model) else: query = query.models(model) query = query.narrow("is_displayed:true") query = query.facet(field) if facet_limit: query = query.facet_limit(facet_limit) if facet_mincount: query = query.facet_mincount(facet_mincount) return query.facet_counts().get("fields", {}).get(field, [])
def search_filter(self, filters=None, *args, **kwargs): sqs = SearchQuerySet() user = kwargs.get('user', None) groups = [] if user and user.is_authenticated(): groups = [g.pk for g in user.group_set.all()] admin = user.profile.is_superuser # permission filters if user: if not user.profile.is_superuser: if not user.is_anonymous(): # (status+status_detail+(anon OR user)) OR (who_can_view__exact) anon_query = Q(allow_anonymous_view=True) user_query = Q(allow_user_view=True) sec1_query = Q(status=True, status_detail='active') user_perm_q = Q(users_can_view__in=[user.pk]) group_perm_q = Q(groups_can_view__in=groups) query = reduce(operator.or_, [anon_query, user_query]) query = reduce(operator.and_, [sec1_query, query]) query = reduce(operator.or_, [query, user_perm_q, group_perm_q]) else: sqs = sqs.filter(allow_anonymous_view=True) else: sqs = sqs.filter(allow_anonymous_view=True) # custom filters for filter in filters: sqs = sqs.filter(content='"%s"' % filter) return sqs.models(self.model)
def get_searchqueryset(self, form): """Get the Haystack searchqueryset (which we treat as a regular Django queryset.""" sqs = SearchQuerySet() if self.model: sqs = sqs.models(self.model) # FIXME: Move somewhere more sensible if settings.PORTAL_HIDE_DRAFTS and not self.request.user.is_staff: sqs = sqs.narrow("publication_status:%d" % models.Resource.PUBLISHED) for facet in self.facetclasses: sqs = facet.apply(sqs) # apply the query if form.is_valid(): sqs = form.filter(sqs) for facetclass in self.facetclasses: sqs = facetclass.narrow(sqs, self.request.GET.getlist( facetclass.paramname)) counts = sqs.facet_counts() current = sqs.query.narrow_queries for facetclass in self.facetclasses: facetclass.parse(counts, current) # FIXME: Find way around assigning the sqs to the instance, # but it seems to be difficult to prevent it from running # multiple times otherwise, e.g. when checking for a spelling # suggestion. self.searchqueryset = sqs return sqs
def _specific_view(user, obj): """ determines if a user has specific permissions to view the object. note this is based only on: (users_can_view contains user) + (groups_can_view contains one of user's groups) """ sqs = SearchQuerySet() sqs = sqs.models(obj.__class__) groups = [g.pk for g in user.group_set.all()] q_primary_key = SQ(primary_key=obj.pk) q_groups = SQ(groups_can_view__in=groups) q_users = SQ(users_can_view__in=[user.pk]) if groups: sqs = sqs.filter(q_primary_key & (q_groups | q_users)) else: sqs = sqs.filter(q_primary_key & q_users) if sqs: return True return False
def handle_save(self, sender, instance, **kwargs): if sender not in self.index_models: return # If IgniteUser was saved and changed name, then update all its authored projects owner_name: if sender == IgniteUser: owner_projects_qs = Project.objects.filter(owner=instance) base_owner_projects_sq = SearchQuerySet() base_owner_projects_sq = base_owner_projects_sq.models(Project) for owner_project_instance in owner_projects_qs: # get owner project from haystack index: owner_projects_sq = base_owner_projects_sq.filter(id=owner_project_instance.id) if owner_projects_sq.count() == 0: # continue till get to the first project found in haystack. # Note: all projects should be found in haystack always, so this would never happen. continue old_owner_name = owner_projects_sq[0].owner_name # if indexed owner_name is different from the current user name: if old_owner_name != instance.name: using_backends = self.connection_router.for_write(instance=owner_project_instance) for using in using_backends: try: index = self.connections[using].get_unified_index().get_index(Project) if hasattr(index, 'update_owner_projects'): # update the owner_name of the owner projects: index.update_owner_projects(owner=instance, using=using) except NotHandled: # TODO: Maybe log it or let the exception bubble? pass break else: super(IgniteSignalProcessor, self).handle_save(sender, instance, **kwargs)
def get_object_list(self, request): # for case no search from haystack.inputs import AutoQuery from haystack.query import SearchQuerySet params = request.GET sqs = SearchQuerySet() if len(params.getlist('content_type')): for content_type in params.getlist('content_type'): sqs = sqs.models(get_model(*content_type.split('.'))) #if params.get('order_by'): # sqs = sqs.order_by(params.get('order_by', '')) if params.get('q', ''): sqs = sqs.filter_or(content=AutoQuery(params.get('q', '').lower())) for k, v in params.iteritems(): if k not in ['q', 'page', 'limit', 'content_type', 'order_by']: sqs = sqs.filter_or(**{k: v}) limit = int(request.GET.get('limit', 20)) page = int(request.GET.get('page', 1)) - 1 object_list = sqs[page * limit:(page * limit + limit)] objects = [] for result in object_list: objects.append(result) return objects
def directory(request, categories=None): sqs = SearchQuerySet() sqs = sqs.models(CourseInfo) if categories: cat_list = categories.lower().strip('/').split('/') category = get_object_or_404(Category, name=cat_list[-1]) children = category.children.all() sqs = sqs.filter(categories=category.name) curr_category = category else: children = Category.objects.filter(parent_category__isnull=True) curr_category = None sqs = sqs.order_by('-rating') try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 courses_paginator = Paginator(sqs, int(request.GET.get('rpp','25'))) try: courses_page = courses_paginator.page(page) except (EmptyPage, InvalidPage): courses_page = courses_paginator.page(courses_paginator.num_pages) render_dict = {'children': children, 'curr_category':curr_category, 'courses_page': courses_page, 'paginator':courses_paginator, 'mod_path':request.path + '?rpp=25' } return render_to_response('classes/directory.html', render_dict , context_instance=RequestContext(request))
def list(self, request): limit = int(request.GET['limit']) if 'limit' in request.GET else 100 offset = int(request.GET['offset']) if 'offset' in request.GET else 0 lower = offset upper = offset + limit from haystack.query import SearchQuerySet # Create new queryset qs = SearchQuerySet() qs = qs.models(self.model) result_list = [] for sr in qs.values(*self.fields)[lower:upper]: result_list.append(sr) hostname = request._request.META['HTTP_HOST'] https = 'https://' if request._request.is_secure() else 'http://' for r in result_list: if 'api_url' in r: r['api_url'] = "{}{}{}".format(https, hostname, r['api_url']) self.paginate_queryset(result_list) self.paginator.count = qs.count() self.paginator.display_page_controls = True return self.get_paginated_response(result_list)
def search_map(request): """Show search results on map""" if request.GET['q']: query = request.GET['q'] else: return HttpResponseRedirect(reverse('site_home')) sqs = SearchQuerySet().all().filter(content=query) documents = sqs.models(Document).filter(published=True) features = sqs.models(Feature).filter_or(name__exact=query, address__exact=query).exclude(address='Greater Whitechapel') images = sqs.models(Image).filter(published=True) media = sqs.models(Media).filter(published=True) contributors = sqs.models(User) return render(request, 'map/search_map.html', {'query': query, 'documents': documents, 'features': features, 'images': images, 'contributors': contributors, 'media': media })
def filter_news(request, default_limit=None): # read hosts list or single host_slugs = parse_union(request) contains = request.GET.get("search") limit = parse_limit( request, default=default_limit) if default_limit else parse_limit(request) start, end = parse_filter_date(request) results = SearchQuerySet() if host_slugs: results = results.filter_or(host_slug__in=host_slugs) if contains: results = results.filter_and(content__contains=contains) if start: results = results.filter_and(published__gte=start) if end: results = results.filter_and(published__lt=end) results = results.models(NewsPost).order_by('-published') if limit: results = results[:limit] posts = [result.object for result in results] return posts
def get_projects_ids_searched_by_lesson_titles(search_query, filter_or=False): search_query_set = SearchQuerySet() search_query_set = search_query_set.models(Lesson) search_params = filter(None, search_query.split(' ')) # If no search params, then return all: if not search_params: return set(search_query_set.values_list('project_id', flat=True)) sq_filter = None for param in search_params: if param.startswith('-'): search_query_set = search_query_set.exclude(content=param[1:]) else: _sq_filter = SQ(content__startswith=param) if sq_filter: if filter_or: sq_filter |= _sq_filter else: sq_filter &= _sq_filter else: sq_filter = _sq_filter # Since sq.exclude.exclude.filter_or returns wrong data, we bypass it with a single .filter in the end: if sq_filter is not None: search_query_set = search_query_set.filter(sq_filter) return set(search_query_set.values_list('project_id', flat=True))
def get_object_list(self, request, **kwargs): q = kwargs.get('query', '') # sqs = SearchQuerySet().filter(SQ(content__contains=q) | SQ(name=q)) # sqs = SearchQuerySet().filter(SQ(content__contains=q) | SQ(content_auto=q)) #sqs = SearchQuerySet().filter(SQ(content=AutoQuery(q)) | SQ(name=AutoQuery(q))) #sqs = SearchQuerySet().filter(content=AutoQuery(q)) sqs = SearchQuerySet().filter(text_auto=AutoQuery(q)) search_models = [] limit_models = request.GET.get('ct', None) if limit_models: for model in limit_models.split(':'): try: search_models.append(apps.get_model(*model.split('.'))) except LookupError as e: pass sqs = sqs.models(*search_models) # TODO: nasty hack here. filter out 'basket' playlists that do not belong to the authenticated user if request.user.is_authenticated(): sqs = sqs.exclude(Q(type='basket') | ~Q(user_pk=request.user.pk)) else: sqs = sqs.exclude(type='basket') sqs = sqs.highlight().load_all() return sqs
def search(self, query=None, *args, **kwargs): # """ # Uses haystack to query articles. # Returns a SearchQuerySet # """ # # update what the status detail should be instead of active # kwargs.update({'status_detail': 'published'}) # return super(MemberAppManager, self).search(query=query, *args, **kwargs) """ Use Django Haystack search index Returns a SearchQuerySet object """ sqs = SearchQuerySet() user = kwargs.get('user', AnonymousUser()) user = impersonation(user) if query: sqs = sqs.auto_query(sqs.query.clean(query)) if user.profile.is_superuser: sqs = sqs.all() # admin else: if user.is_anonymous(): sqs = anon2_sqs(sqs) # anonymous else: pass sqs = user2_sqs(sqs, user=user) # user return sqs.models(self.model)
def _specific_view(user, obj): """ determines if a user has specific permissions to view the object. note this is based only on: (users_can_view contains user) + (groups_can_view contains one of user's groups) """ sqs = SearchQuerySet() sqs = sqs.models(obj.__class__) groups = [g.pk for g in user.group_set.all()] q_primary_key = SQ(primary_key=obj.pk) q_groups = SQ(groups_can_view__in=groups) q_users = SQ(users_can_view__in=[user.pk]) if groups: sqs = sqs.filter(q_primary_key & (q_groups | q_users)) else: sqs = sqs.filter(q_primary_key & q_users) if sqs: return True return False
def suggestions(request): MODEL_MAP = {'Product': Product, 'Service': Service, 'Contact': Contact} model_names = request.GET.getlist('models') models = [] for name in model_names: if name in MODEL_MAP: models.append(MODEL_MAP[name]) if len(models) == 0: models.extend((Product, Service, Contact)) terms = request.GET['term'].strip() results = SearchQuerySet().auto_query(terms) results = results.models(*models).exclude(tags='self')[:MAX_SUGGESTIONS] guesses = [] for r in results: guesses.append({ 'id': r.pk, 'name': r.name, 'summary': r.summary, 'type': r.verbose_name, 'type_id': r.object.content_type().id, 'url': r.object.get_view_url(), }) params = request.GET.copy() guesses.append({ 'name': "See all results for '" + terms + "'", 'more': True, 'url': reverse(view) + "?" + urllib.urlencode(params), }) return HttpResponse(json.dumps(guesses), mimetype='application/json')
def render(self, context): try: model_instance = self.model.resolve(context) sqs = SearchQuerySet() if not self.for_types is None: intermediate = template.Variable(self.for_types) for_types = intermediate.resolve(context).split(',') search_models = [] for model in for_types: model_class = haystack_get_model(*model.split('.')) if model_class: search_models.append(model_class) sqs = sqs.models(*search_models) sqs = sqs.more_like_this(model_instance) if not self.limit is None: sqs = sqs[:self.limit] context[self.varname] = sqs except: pass return ''
def _specific_view(user, obj): """ determines if a user has specific permissions to view the object. note this is based only on: (users_can_view contains user) + (groups_can_view contains one of user's groups) """ sqs = SearchQuerySet() sqs = sqs.models(obj.__class__) groups = [g.pk for g in user.group_set.all()] q_primary_key = SQ(primary_key=obj.pk) q_groups = SQ(groups_can_view__in=groups) q_users = SQ(users_can_view__in=[user.pk]) if groups: sqs = sqs.filter(q_primary_key & (q_groups | q_users)) else: sqs = sqs.filter(q_primary_key & q_users) if sqs: # Make sure the index isn't doing something unexpected with the query, # like when the Whoosh StopFilter caused the primary_key portion of the # query to be ignored. assert len(sqs) == 1, "Index returned an unexpected result set when searching for view permissions on an object" return True return False
def render(self, context): try: model_instance = self.model.resolve(context) sqs = SearchQuerySet() if not self.for_types is None: intermediate = template.Variable(self.for_types) for_types = intermediate.resolve(context).split(',') search_models = [] for model in for_types: model_class = models.get_model(*model.split('.')) if model_class: search_models.append(model_class) sqs = sqs.models(*search_models) sqs = sqs.more_like_this(model_instance) if not self.limit is None: sqs = sqs[:self.limit] context[self.varname] = sqs except: pass return ''
def get(self, request, keyword=None, format=None): result = [] total = 0 offset = int(request.GET.get('offset', '0')) limit = int(request.GET.get('limit', '10')) if keyword is not None: words = keyword.split(' ') result = SearchQuerySet() for word in words: result = result.filter(content__exact=word) result = result.models(Reply) total = result.count() result = result[offset:(offset + limit)] for r in result: print(r.score) result = [r.object for r in result] for reply in result: reply.question = strip_tags(reply.question)[0:100] reply.answer = strip_tags(reply.answer)[0:100] serializer = ReplySerializer(result, many=True) return JsonResponse( { 'data': serializer.data, 'total': total, 'limit': limit, 'offset': offset }, safe=False)
def search(query, limit=20, models=None, as_list=False): print "Searching for: %s" % query if not query: return [] try: sqs = SearchQuerySet() # clean query q = sqs.query.clean(query) # add models if models is not None: if not isinstance(models, (list, tuple)): models = (models, ) sqs = sqs.models(*models) # ignore letters keywords = [k for k in q.split() if len(k) > 1] # search word by word for keyword in keywords: sqs.query.add_filter(SQ(title="%s^2.0" % keyword)) # order by score and popularity sqs = sqs.order_by('-score', '-popularity') # add highlight sqs = sqs.highlight() sqs = sqs[:limit] except Exception, e: # on error show empty result print e # TODO: log error sqs = []
def search(self, query=None, *args, **kwargs): """ Uses haystack to query forms. Returns a SearchQuerySet """ sqs = SearchQuerySet() user = kwargs.get('user', None) # check to see if there is impersonation if hasattr(user, 'impersonated_user'): if isinstance(user.impersonated_user, User): user = user.impersonated_user is_an_admin = user.profile.is_superuser if query: sqs = sqs.auto_query(sqs.query.clean(query)) if user: if not is_an_admin: return [] else: sqs = sqs.all() if user: if not is_an_admin: return [] return sqs.models(self.model).order_by('-create_dt')
def get_searchqueryset(self, form): """Get the Haystack searchqueryset (which we treat as a regular Django queryset.""" sqs = SearchQuerySet() if self.model: sqs = sqs.models(self.model) # FIXME: Move somewhere more sensible if settings.PORTAL_HIDE_DRAFTS and not self.request.user.is_staff: sqs = sqs.narrow("publication_status:%d" % models.Resource.PUBLISHED) for facet in self.facetclasses: sqs = facet.apply(sqs) # apply the query if form.is_valid(): sqs = form.filter(sqs) for facetclass in self.facetclasses: sqs = facetclass.narrow( sqs, self.request.GET.getlist(facetclass.paramname)) counts = sqs.facet_counts() current = sqs.query.narrow_queries for facetclass in self.facetclasses: facetclass.parse(counts, current) # FIXME: Find way around assigning the sqs to the instance, # but it seems to be difficult to prevent it from running # multiple times otherwise, e.g. when checking for a spelling # suggestion. self.searchqueryset = sqs return sqs
def get_projects_ids_searched_by_title_tags_author(search_query, filter_or=False): search_query_set = SearchQuerySet() search_query_set = search_query_set.models(Project) search_params = filter(None, search_query.split(' ')) # If no search params, then return all: if not search_params: return search_query_set.all() sq_filter = None for param in search_params: if param.startswith('-'): param = param[1:] # remove - sign search_query_set = search_query_set.exclude(title=param) search_query_set = search_query_set.exclude(tags=param) search_query_set = search_query_set.exclude(owner_name=param) else: _sq_filter = SQ(title=param) _sq_filter |= SQ(tags=param) _sq_filter |= SQ(owner_name=param) if sq_filter: if filter_or: sq_filter |= _sq_filter else: sq_filter &= _sq_filter else: sq_filter = _sq_filter # Since sq.exclude.exclude.filter_or returns wrong data, we bypass it with a single .filter in the end: if sq_filter is not None: search_query_set = search_query_set.filter(sq_filter) return search_query_set.values_list('pk', flat=True)
def handle(self, *args, **options): sqs = SearchQuerySet() users = sqs.models(User).all().count() images = sqs.models(Image).all().count() integration = 0 for i in sqs.models(Image).all(): integration += i.integration integration = int(integration / 3600.0) gs = GlobalStat( users = users, images = images, integration = integration) gs.save()
def render(self, context): try: model_instance = self.model.resolve(context) sqs = SearchQuerySet() if self.for_types is not None: intermediate = template.Variable(self.for_types) for_types = intermediate.resolve(context).split(",") search_models = [] for model in for_types: model_class = haystack_get_model(*model.split(".")) if model_class: search_models.append(model_class) sqs = sqs.models(*search_models) sqs = sqs.more_like_this(model_instance) if self.limit is not None: sqs = sqs[: self.limit] context[self.varname] = sqs except Exception as exc: logging.warning( "Unhandled exception rendering %r: %s", self, exc, exc_info=True ) return ""
class TestSearch(TestCase): def setUp(self): for key, opts in haystack.connections.connections_info.items(): haystack.connections.reload(key) call_command('clear_index', interactive=False, verbosity=0) self.u = User.objects.create_user(username="******", password="******") self.u.first_name = "FirstName" self.u.last_name = "LastName" self.u.save() self.profile = UserProfile.objects.get(user=self.u) self.profile.phone_number = "(111) 111-1111" self.profile.save() self.sqs = SearchQuerySet() self.client.login(username="******", password="******") def test_search_view(self): response = self.client.get("/search/") self.assertEqual(response.status_code, 200) self.assertContains(response, "Search") def test_model_backend(self): self.assertEqual(UserProfile.objects.count(), self.sqs.models(UserProfile).count()) self.assertEqual(self.profile, self.sqs.facet(self.u.first_name)[0].object) self.assertEqual(self.profile, self.sqs.facet(self.u.last_name)[0].object) self.assertEqual(self.profile, self.sqs.facet(self.profile.phone_number)[0].object)
def search_filter(self, filters=None, *args, **kwargs): sqs = SearchQuerySet() user = kwargs.get('user', None) groups = [] if user and user.is_authenticated(): groups = [g.pk for g in user.group_set.all()] admin = user.profile.is_superuser # permission filters if user: if not user.profile.is_superuser: if not user.is_anonymous(): # (status+status_detail+(anon OR user)) OR (who_can_view__exact) anon_query = Q(allow_anonymous_view=True) user_query = Q(allow_user_view=True) sec1_query = Q(status=True, status_detail='active') user_perm_q = Q(users_can_view__in=[user.pk]) group_perm_q = Q(groups_can_view__in=groups) query = reduce(operator.or_, [anon_query, user_query]) query = reduce(operator.and_, [sec1_query, query]) query = reduce(operator.or_, [query, user_perm_q, group_perm_q]) else: sqs = sqs.filter(allow_anonymous_view=True) else: sqs = sqs.filter(allow_anonymous_view=True) # custom filters for filter in filters: sqs = sqs.filter(content='"%s"' % filter) return sqs.models(self.model)
def _specific_view(user, obj): """ determines if a user has specific permissions to view the object. note this is based only on: (users_can_view contains user) + (groups_can_view contains one of user's groups) """ sqs = SearchQuerySet() sqs = sqs.models(obj.__class__) groups = [g.pk for g in user.user_groups.all()] q_primary_key = SQ(primary_key=obj.pk) q_groups = SQ(groups_can_view__in=groups) q_users = SQ(users_can_view__in=[user.pk]) if groups: sqs = sqs.filter(q_primary_key & (q_groups | q_users)) else: sqs = sqs.filter(q_primary_key & q_users) if sqs: # Make sure the index isn't doing something unexpected with the query, # like when the Whoosh StopFilter caused the primary_key portion of the # query to be ignored. assert len( sqs ) == 1, "Index returned an unexpected result set when searching for view permissions on an object" return True return False
def get_queryset(self, query_args): # Create new queryset qs = SearchQuerySet() # Are we searching all models or just a specific one (depends on # parameter set in View instantiation) if self.search_model is not None: qs = qs.models(self.search_model) # Do we have a query or are we just getting all of them? if 'q' in query_args: qry = query_args['q'] ## Currently deactivated due to policy decision to allow the users ## themselves to choose the granularity and fuzzyness of the search ## # fuzzify search # qry = u'{}~'.format(qry.replace(' ', '~ ')) qs = qs.auto_query(qry) elif 'parl_id' in query_args: qs = qs.filter(parl_id=query_args['parl_id']) if 'llp_numeric' in query_args: qs = qs.filter(llps_numeric=query_args['llp_numeric']) return (qs.all(), None) # Filter by facets if query_args['facet_filters']: for facet_field in query_args['facet_filters'].keys(): # We use narrow to limit the index entries beforehand, but # need to use filter afterwards to remove partly correct results # For instance, searching for Steyr (Oberoesterreich) yielded # everyone from Oberoesterreich until filtering by it again. qs = qs.narrow(u"{}:{}".format( facet_field, qs.query.clean(query_args['facet_filters'][facet_field]) )).filter( **{facet_field: query_args['facet_filters'][facet_field]}) # Retrieve facets and facet_counts facet_counts = [] if self.facet_fields: facets = qs for facet_field in self.facet_fields: if self.facet_fields[facet_field]['type'] == 'date': facets = facets.date_facet( facet_field, start_date=datetime.date(1900, 1, 1), end_date=datetime.date(2050, 1, 1), gap_by='month') if self.facet_fields[facet_field]['type'] == 'field': facets = facets.facet(facet_field) facet_counts = facets.facet_counts() # Get results and return them if 'only_facets' in query_args: result = {} else: result = qs.all() return (result, facet_counts)
def render(self, context): try: model_instance = self.model.resolve(context) sqs = SearchQuerySet() if self.for_types is not None: intermediate = template.Variable(self.for_types) for_types = intermediate.resolve(context).split(",") search_models = [] for model in for_types: model_class = haystack_get_model(*model.split(".")) if model_class: search_models.append(model_class) sqs = sqs.models(*search_models) sqs = sqs.more_like_this(model_instance) if self.limit is not None: sqs = sqs[:self.limit] context[self.varname] = sqs except Exception as exc: logging.warning("Unhandled exception rendering %r: %s", self, exc, exc_info=True) return ""
def search(self, query=None, *args, **kwargs): """ Uses haystack to query news. Returns a SearchQuerySet """ sqs = SearchQuerySet() user = kwargs.get('user', None) # check to see if there is impersonation if hasattr(user,'impersonated_user'): if isinstance(user.impersonated_user, User): user = user.impersonated_user is_an_admin = user.profile.is_superuser if query: sqs = sqs.auto_query(sqs.query.clean(query)) if user: if not is_an_admin: return [] else: sqs = sqs.all() if user: if not is_an_admin: return [] return sqs.models(self.model).order_by('-update_dt')
class LiveWhooshMultiSearchQuerySetTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(LiveWhooshMultiSearchQuerySetTestCase, self).setUp() # Stow. self.old_whoosh_path = settings.HAYSTACK_CONNECTIONS['default']['PATH'] self.old_ui = connections['default'].get_unified_index() self.ui = UnifiedIndex() self.wmmi = WhooshMockSearchIndex() self.wamsi = WhooshAnotherMockSearchIndex() self.ui.build(indexes=[self.wmmi, self.wamsi]) self.sb = connections['default'].get_backend() connections['default']._index = self.ui self.sb.setup() self.raw_whoosh = self.sb.index self.parser = QueryParser(self.sb.content_field_name, schema=self.sb.schema) self.sb.delete_index() self.wmmi.update() self.wamsi.update() self.sqs = SearchQuerySet() def tearDown(self): if os.path.exists(settings.HAYSTACK_CONNECTIONS['default']['PATH']): shutil.rmtree(settings.HAYSTACK_CONNECTIONS['default']['PATH']) settings.HAYSTACK_CONNECTIONS['default']['PATH'] = self.old_whoosh_path connections['default']._index = self.old_ui super(LiveWhooshMultiSearchQuerySetTestCase, self).tearDown() def test_searchquerysets_with_models(self): sqs = self.sqs.all() self.assertEqual(sqs.query.build_query(), u'*') self.assertEqual(len(sqs), 25) sqs = self.sqs.models(MockModel) self.assertEqual(sqs.query.build_query(), u'*') self.assertEqual(len(sqs), 23) sqs = self.sqs.models(AnotherMockModel) self.assertEqual(sqs.query.build_query(), u'*') self.assertEqual(len(sqs), 2)
def view(request): terms = request.GET.get('term') results = SearchQuerySet().auto_query(terms) results = results.models(Product, Service, Contact) count = results.count() return render_to_response('common/search.html', dict(terms=terms, count=count), context_instance=RequestContext(request))
def post(self, request, *args, **kwargs): query = request.POST.get('query') if not query: return self.bad_request() sqs = SearchQuerySet() sqs = sqs.models(Tag).filter(content__exact=normalize(query)) lst = [{'value': sr.object.name, 'data': sr.object.posts.count()} for sr in sqs.all()] return JsonResponse({'status': 'success', 'query': query, 'suggestions': lst})