def personal_search(request): """ The user can search any item within his own collections and can search **only shared items** of other users TODO: Build a hash table to store item_id in the result of user_item to reduce time from O(n^2) to O(n) Reference: http://docs.haystacksearch.org/dev/searchqueryset_api.html#field-lookups """ #Two parameters to tune RESULTS_PER_PAGE = 10 load_all = False query = request.GET['q'].strip() #Heystack only accepts key name as 'q' user_id = int(request.GET['pid']) if query == '': sqs = EmptySearchQuerySet() else: searchqueryset = SearchQuerySet() if user_id == request.user.pk: pronoun = '我' own_items = User_Item.objects.filter(user__pk=request.user.pk) else: pronoun = Profile.objects.get(pk=user_id).name own_items = User_Item.objects.filter(user__pk=user_id).exclude(status=1) own_items_ids = [] for oi in own_items: own_items_ids.append(int(oi.item_id)) sqs = searchqueryset.auto_query(query).filter(primary_key__in=own_items_ids) if load_all: sqs = sqs.load_all() paginator = Paginator(sqs, RESULTS_PER_PAGE) try: page = paginator.page(request.GET.get('page', 1)) feeds_id = '' for result in page.object_list: feeds_id += str(result.object.id) + ',' feeds_id = feeds_id[:-1] topics_of_item_dict = get_topics_of_item(feeds_id, request.user.pk) friends_of_item_dict = get_friends_of_item(feeds_id, request.user.pk) user_item_status_dict = get_user_items(feeds_id, request.user.pk) except InvalidPage: raise Http404 context = { 'query': query, 'page': page, 'page_type':'search', 'topics_of_item_dict':topics_of_item_dict, 'friends_of_item_dict':friends_of_item_dict, 'user_item_status_dict':user_item_status_dict, 'paginator': paginator, 'suggestion': None, 'pronoun': pronoun, 'num_results': len(sqs), 'user_id': user_id } from django.template import add_to_builtins add_to_builtins('haystack.templatetags.highlight') return render_to_response('main/search/personal_search_results.html', context, context_instance=RequestContext(request))
class EmptySearchQuerySetTestCase(TestCase): def setUp(self): super(EmptySearchQuerySetTestCase, self).setUp() self.esqs = EmptySearchQuerySet() def test_get_count(self): self.assertEqual(self.esqs.count(), 0) self.assertEqual(len(self.esqs.all()), 0) def test_filter(self): sqs = self.esqs.filter(content='foo') self.assert_(isinstance(sqs, EmptySearchQuerySet)) self.assertEqual(len(sqs), 0) def test_exclude(self): sqs = self.esqs.exclude(content='foo') self.assert_(isinstance(sqs, EmptySearchQuerySet)) self.assertEqual(len(sqs), 0) def test_slice(self): sqs = self.esqs.filter(content='foo') self.assert_(isinstance(sqs, EmptySearchQuerySet)) self.assertEqual(len(sqs), 0) self.assertEqual(sqs[:10], []) try: sqs[4] self.fail() except IndexError: pass
def search(request): """ Modification/Combination based on two haystack classes: 1,haystack/views/SearchView 2,haystack/forms/SearchForm/search() Reference: #. http://docs.haystacksearch.org/dev/ #. http://lucene.apache.org/solr/tutorial.html """ #Two parameters to tune RESULTS_PER_PAGE = 10 load_all = False query = request.GET['q'].strip() #Heystack only accepts key name as 'q' if query == '': sqs = EmptySearchQuerySet() else: searchqueryset = SearchQuerySet() sqs = searchqueryset.auto_query(query) #The default auto_query method has been modified to use OR instead of AND if load_all: sqs = sqs.load_all() paginator = Paginator(sqs, RESULTS_PER_PAGE) try: page = paginator.page(request.GET.get('page', 1)) feeds_id = '' for result in page.object_list: feeds_id += str(result.object.id) + ',' #If an item is deleted and not reindexed, then error feeds_id = feeds_id[:-1] topics_of_item_dict = get_topics_of_item(feeds_id, request.user.pk) friends_of_item_dict = get_friends_of_item(feeds_id, request.user.pk) user_item_status_dict = get_user_items(feeds_id, request.user.pk) except InvalidPage: raise Http404 context = { 'query': query, 'page': page, 'page_type':'search', 'topics_of_item_dict':topics_of_item_dict, 'friends_of_item_dict':friends_of_item_dict, 'user_item_status_dict':user_item_status_dict, 'paginator': paginator, 'suggestion': None, 'num_results': len(sqs), } from django.template import add_to_builtins add_to_builtins('haystack.templatetags.highlight') #Changed haystack.utils.Highlighter.highliht to not use window return render_to_response('main/search/web_search_results.html', context, context_instance=RequestContext(request))
def basic_search(request, template='search/search.html', load_all=True, form_class=ModelSearchForm, searchqueryset=None, extra_context=None, results_per_page=None): """ A more traditional view that also demonstrate an alternative way to use Haystack. Useful as an example of for basing heavily custom views off of. Also has the benefit of thread-safety, which the ``SearchView`` class may not be. Template:: ``search/search.html`` Context:: * form An instance of the ``form_class``. (default: ``ModelSearchForm``) * page The current page of search results. * paginator A paginator instance for the results. * query The query received by the form. """ query = '' results = EmptySearchQuerySet() if request.GET.get('q'): form = form_class(request.GET, searchqueryset=searchqueryset, load_all=load_all) if form.is_valid(): query = form.cleaned_data['q'] results = form.search() else: form = form_class(searchqueryset=searchqueryset, load_all=load_all) paginator = Paginator(results, results_per_page or RESULTS_PER_PAGE) try: page = paginator.page(int(request.GET.get('page', 1))) except InvalidPage: raise Http404("No such page of results!") types = types_find() # 获取新品信息 new_skus = f_new_skus() context = { 'form': form, 'page': page, 'paginator': paginator, 'query': query, 'suggestion': None, 'types': types, # 商品类型 'new_skus': new_skus, } if results.query.backend.include_spelling: context['suggestion'] = form.get_suggestion() if extra_context: context.update(extra_context) return render(request, template, context)
def post(self, request, load_all=True, searchqueryset=None): """ 首页查询功能 :param request: :return: """ # 127.0.0.1:8000/v1/goods/search/ from dadashop.settings import HAYSTACK_SEARCH_RESULTS_PER_PAGE query = '' page_size = HAYSTACK_SEARCH_RESULTS_PER_PAGE results = EmptySearchQuerySet() if request.POST.get('q'): form = ModelSearchForm(request.POST, searchqueryset=searchqueryset, load_all=load_all) if form.is_valid(): query = form.cleaned_data['q'] results = form.search() else: form = ModelSearchForm(searchqueryset=searchqueryset, load_all=load_all) paginator = Paginator(results, page_size) try: page = paginator.page(int(request.POST.get('page', 1))) except: result = {'code': 40200, 'error': '页数有误,小于0或者大于总页数'} return JsonResponse(result) # 记录查询信息 context = { 'form': form, 'page': page, 'paginator': paginator, 'query': query, } sku_list = [] # print(len(page.object_list)) for result in page.object_list: sku = { 'skuid': result.object.id, 'name': result.object.name, 'price': result.object.price, } # 获取图片 sku_image = str(result.object.default_image_url) sku['image'] = sku_image sku_list.append(sku) result = { "code": 200, "data": sku_list, 'paginator': { 'pagesize': page_size, 'total': len(results) }, 'base_url': PIC_URL } return JsonResponse(result)
def get_queryset(self): self.query_string = re.sub(r'[^\w ]', '', self.request.GET.get('q', '')) if self.query_string: return SearchQuerySet().filter( content=AutoQuery(self.query_string)) else: return EmptySearchQuerySet()
def get_queryset(self, *args, **kwargs): request = self.request queryset = EmptySearchQuerySet() if request.GET.get('q') is not None: query = request.GET.get('q') queryset = SearchQuerySet().autocomplete(content_auto=query)[:5] return queryset
def get_queryset(self): request = self.request queryset = EmptySearchQuerySet() if request.GET.get('q', ''): query = request.GET.get('q', '') queryset = SearchQuerySet().models(Faculty).filter(content=query) return [i.object for i in queryset]
def search(request, template='search/search.html', load_all=True, form_class=ModelSearchForm, searchqueryset=None, context_class=RequestContext, extra_context=None, results_per_page=None): query = '' results = EmptySearchQuerySet() # We have a query. if request.GET.get('q'): if request.user.is_authenticated() and '--mine' in request.GET.get( 'q'): searchqueryset = SearchQuerySet().filter( author=request.user).order_by('-pub_date') else: searchqueryset = SearchQuerySet().filter( Q(public=True) | Q(author=request.user)).order_by('-pub_date') form = ModelSearchForm(request.GET, searchqueryset=searchqueryset, load_all=load_all) if form.is_valid(): query = form.cleaned_data['q'] results = form.search() else: form = form_class(searchqueryset=searchqueryset, load_all=load_all) paginator = Paginator(results, results_per_page or RESULTS_PER_PAGE) try: page = paginator.page(int(request.GET.get('page', 1))) except InvalidPage: raise Http404("No such page of results!") context = { 'form': form, 'has_snipts': True, 'page': page, 'paginator': paginator, 'query': query, 'suggestion': None, } if results.query.backend.include_spelling: context['suggestion'] = form.get_suggestion() if extra_context: context.update(extra_context) return render_to_response(template, context, context_instance=context_class(request))
def get(self, request, fmt=None): context = {} if fmt: query = '' results = EmptySearchQuerySet() form = self.form_class(request.GET, searchqueryset=self.searchqueryset, load_all=True) if form.is_valid(): print form.cleaned_data query = form.cleaned_data['q'] order_by = request.GET.get('order_by', None) results = form.search(order_by) else: results = form.no_query_found() if self.facets: for facet in self.facets: results = results.facet(facet[0], mincount=1, sort=facet[1]) context['facets'] = results.facet_counts() paginator = Paginator(results, 25) page = request.GET.get('page', '1') try: content = paginator.page(page) except PageNotAnInteger: content = paginator.page(1) except EmptyPage: content = paginator.page(paginator.num_pages) context['content'] = content context['paginator'] = paginator context['query'] = query context['form'] = form return self.render_to_format(request, context, self.template_name, fmt) else: params = [] if not request.GET.get('q') and not request.GET.get('order_by'): params.append('order_by={}'.format(self.default_order)) for param in self.params: print param['name'] param_value = request.GET.get(param['name'], param['default']) if param_value: params.append('{}={}'.format(param['name'], param_value)) print params context['params'] = '&'.join(params) context['status_code'] = 303 context['additional_headers'] = {'location': self.path} context['content'] = None return self.render(request, context, self.template_name)
class EmptySearchQuerySetTestCase(TestCase): def setUp(self): super(EmptySearchQuerySetTestCase, self).setUp() self.esqs = EmptySearchQuerySet() def test_get_count(self): self.assertEqual(self.esqs.count(), 0) self.assertEqual(len(self.esqs.all()), 0) def test_filter(self): sqs = self.esqs.filter(content='foo') self.assert_(isinstance(sqs, EmptySearchQuerySet)) self.assertEqual(len(sqs), 0) def test_exclude(self): sqs = self.esqs.exclude(content='foo') self.assert_(isinstance(sqs, EmptySearchQuerySet)) self.assertEqual(len(sqs), 0)
def get_extra_context(self, request, form): if form.cleaned_data['q']: users = SearchQuerySet().models(User).load_all().auto_query( form.cleaned_data['q']) else: users = EmptySearchQuerySet() return { 'user_results': users, }
def get_queryset(self, *args, **kwargs): request = self.request queryset = EmptySearchQuerySet() if request.GET.get('q'): query = request.GET.get('q') queryset = SearchQuerySet().auto_query(query) return queryset
def __init__(self, instance=None, data=empty, **kwargs): super(HaystackSerializer, self).__init__(instance, data, **kwargs) if not self.Meta.index_classes and not self.Meta.serializers: raise ImproperlyConfigured("You must set either the 'index_classes' or 'serializers' " "attribute on the serializer Meta class.") if not self.instance: self.instance = EmptySearchQuerySet()
def get_queryset(self): request = self.request queryset = EmptySearchQuerySet() if request.GET.get('q', ''): query = request.GET.get('q', '') queryset = SearchQuerySet().models(Notice).filter( content=query).order_by('-date') return [i.object for i in queryset]
def get_results(self, request, form, query): """ Fetches the results via the form. Returns an empty list if there's no query to search with. """ if query: return form.search() return EmptySearchQuerySet()
def no_query_found(self): """ Determines the behavior when no query was found. By default, no results are returned (``EmptySearchQuerySet``). Should you want to show all results, override this method in your own ``SearchForm`` subclass and do ``return self.searchqueryset.all()``. """ return EmptySearchQuerySet()
def get_results(self, request, form, query): if query and form.is_valid(): sqs = self.searchqueryset.auto_query( form.cleaned_data['q']).models(Article).load_all() for facet in ('section', 'tag', 'pub_date'): key = 'facet_%s' % facet if key in request.GET and request.GET[key]: sqs = sqs.narrow('%s:%s' % (facet, request.GET[key])) return sqs return EmptySearchQuerySet()
def oa_haystack_search(context, nodelist, *args, **kwargs): context.push() namespace = get_namespace(context) dimension = kwargs.get('search_key', None) POST = kwargs.get('POST', None) load_all = True form_class = ModelSearchForm searchqueryset = None context_class = RequestContext extra_context = None results_per_page = None query = '' results = EmptySearchQuerySet() if POST is not None: form = form_class(POST, searchqueryset=searchqueryset, load_all=load_all) if form.is_valid(): query = form.cleaned_data['q'] results = form.search() elif dimension is not None: query = dimension form = form_class({'q': dimension}, searchqueryset=searchqueryset, load_all=load_all) results = form.search() elif query == '': form = form_class(searchqueryset=searchqueryset, load_all=load_all) paginator = Paginator(results, results_per_page or RESULTS_PER_PAGE) try: page = paginator.page(int(POST.get('page', 1))) except InvalidPage: namespace['error'] = "No Such Page of Results" namespace['form'] = form namespace['page'] = page namespace['paginator'] = paginator namespace['query'] = query if getattr(settings, 'HAYSTACK_INCLUDE_SPELLING', False): namespace['suggestion'] = form.get_suggestion() else: namespace['suggestion'] = None output = nodelist.render(context) context.pop() return output
def search(self): sqs = super(SearchForm, self).search() if self.is_valid(): data = self.cleaned_data if any(data.values()): if data['from_date']: sqs = sqs.filter(date__gte=data['from_date']) if data['to_date']: sqs = sqs.filter(date__lt=data['to_date']) return sqs return EmptySearchQuerySet()
def get_queryset(self, *args, **kwargs): request = self.request queryset = EmptySearchQuerySet() if request.GET.get('q') is not None: query = request.GET.get('q') sub = SearchQuerySet().models(User).filter( text__contains=query).values_list('username', flat=True) queryset = User.objects.filter(username__in=sub) return queryset
def search(self, query): if not query: return EmptySearchQuerySet() # OPTIMIZE: the number of public projects can increase substantially # causing a really high number of project_ids to be sended to # elasticsearch projects = Project.objects.public_or_collaborate(self.request.user) return RelatedSearchQuerySet()\ .filter(project_id__in=projects.values_list('pk', flat=True))\ .filter(SQ(content__contains=Clean(query)) | SQ(title__contains=Clean(query)))
def get_results(self): if not self.form.is_valid(): return EmptySearchQuerySet() if not self.form.cleaned_data.get('q'): return EmptySearchQuerySet() #加重含学生学院字段的通知的权重 if self.request.session.get(SESSION_KEY, False): id = self.request.session[SESSION_KEY] self.user = Userinfo.objects.get(pk=id) recom=self.mysearchqueryset.boost(self.user.college,1.2)\ .auto_query(self.form.cleaned_data['q']).order_by('-pubtime','-glances','-download') else: recom = 1 #先对title字段的搜索匹配效果加成,然后执行检索,再按发布时间、浏览量排序 sqs=self.mysearchqueryset.auto_query(self.form.cleaned_data['q'])\ .order_by('-pubtime','-glances','-download') if recom != 1: sqs = recom[0:1] + sqs[1:3] + recom[1:2] + sqs[3:5] + recom[ 2:3] + sqs[5:] return sqs
def get_queryset(self, *args, **kwargs): request = self.request queryset = EmptySearchQuerySet() if request.GET.get('q') is not None: query = request.GET.get('q') sub = SearchQuerySet().models(Article).filter( text__icontains=query).values_list('slug', flat=True) queryset = Article.objects.filter(slug__in=sub) return queryset
def get_results(self, force_update=False): """ Return the final page of results """ if not settings.INDEX_ACTIVATED: return EmptySearchQuerySet() if force_update or self.results is None: self.update_results() return self.results
def get_queryset(self, *args, **kwargs): models = (Transaction, Wallet) sq = SQ() request = self.request results = EmptySearchQuerySet() if 'query' in request.GET: for token in re.findall(r'[\w]+', request.GET['query']): sq |= SQ(content=token) sq |= SQ(content=request.GET['query']) results = SearchQuerySet().models(*models).filter(sq).exclude(group=Raw('[* TO *]')) return results
def make_query(self, fields, keywords, queryset=None): """ Create the query for haystack for searching in `fields ` for documents with `keywords`. All keywords are ANDed, and if a keyword starts with a "-" all document with it will be excluded. """ if not keywords or not fields: return EmptySearchQuerySet() if not queryset: queryset = SearchQuerySet() q = None only_exclude = True for keyword in keywords: exclude = False if keyword.startswith('-') and len(keyword) > 1: exclude = True keyword = keyword[1:] else: only_exclude = False keyword = queryset.query.clean(keyword) q_keyword = None for field in fields: q_field = SQ(**{field: keyword}) if q_keyword: q_keyword = q_keyword | q_field else: q_keyword = q_field if exclude: q_keyword = ~q_keyword if q: q = q & q_keyword else: q = q_keyword if q: if only_exclude and len(keywords) > 1: # it seems that solr cannot manage only exclude when we have many of them # so we AND a query that we not match : the same as for ".models(self.model)" q = SQ(django_ct='core.%s' % self.model_name) & q return queryset.filter(q) else: return queryset
def get_featured_jobs(*args, **kwargs): """ Uses get_jobs to return a SearchQuerySet of featured jobs Passes arguments onto get_jobs, and overwrites custom_facets with site featured facets if they exist. """ if settings.FEATURED_FACET: kwargs.update(custom_facets=settings.FEATURED_FACET) featured_jobs = get_jobs(*args, **kwargs) else: featured_jobs = EmptySearchQuerySet() return featured_jobs
def get_queryset(self): """Return the list of items for this view. This method overrides the default method, as all items were being returned when no query parameters was given (not a blank query). Returns: QuerySet for view. """ if self.request.GET: return super(CustomSearchView, self).get_queryset() else: return EmptySearchQuerySet()
def get_queryset(self, *args, **kwargs): request = self.request queryset = EmptySearchQuerySet() query = request.GET.dict() flag = True for k, v in query.iteritems(): if not k in ['q', 'state', 'district', 'taluk', 'circle', 'region', 'division', 'delivery_status', 'pin_code', 'office_name']: flag = False if flag: if query.get('q'): query['content'] = query.pop('q') queryset = SearchQuerySet().filter(**query) return queryset
def get_queryset(self, *args, **kwargs): #TODO: need to make this robust enough so it doesnt return all of the objects if nothing matches for body/title request = self.request queryset = EmptySearchQuerySet() body = self.request.query_params.get('body', None) title = self.request.query_params.get('title', None) if body: queryset = SearchQuerySet().filter(body=body) elif title: queryset = SearchQuerySet().filter(title=title) else: queryset = ToDo.objects.all() return queryset
class EmptySearchQuerySetTestCase(TestCase): def setUp(self): super(EmptySearchQuerySetTestCase, self).setUp() self.esqs = EmptySearchQuerySet() def test_get_count(self): self.assertEqual(self.esqs.count(), 0) self.assertEqual(len(self.esqs.all()), 0) def test_filter(self): sqs = self.esqs.filter(content="foo") self.assertTrue(isinstance(sqs, EmptySearchQuerySet)) self.assertEqual(len(sqs), 0) def test_exclude(self): sqs = self.esqs.exclude(content="foo") self.assertTrue(isinstance(sqs, EmptySearchQuerySet)) self.assertEqual(len(sqs), 0) def test_slice(self): sqs = self.esqs.filter(content="foo") self.assertTrue(isinstance(sqs, EmptySearchQuerySet)) self.assertEqual(len(sqs), 0) self.assertEqual(sqs[:10], []) try: sqs[4] self.fail() except IndexError: pass def test_dictionary_lookup(self): """ Ensure doing a dictionary lookup raises a TypeError so EmptySearchQuerySets can be used in templates. """ self.assertRaises(TypeError, lambda: self.esqs["count"])
class EmptySearchQuerySetTestCase(TestCase): def setUp(self): super(EmptySearchQuerySetTestCase, self).setUp() self.esqs = EmptySearchQuerySet() def test_get_count(self): self.assertEqual(self.esqs.count(), 0) self.assertEqual(len(self.esqs.all()), 0) def test_filter(self): sqs = self.esqs.filter(content='foo') self.assertTrue(isinstance(sqs, EmptySearchQuerySet)) self.assertEqual(len(sqs), 0) def test_exclude(self): sqs = self.esqs.exclude(content='foo') self.assertTrue(isinstance(sqs, EmptySearchQuerySet)) self.assertEqual(len(sqs), 0) def test_slice(self): sqs = self.esqs.filter(content='foo') self.assertTrue(isinstance(sqs, EmptySearchQuerySet)) self.assertEqual(len(sqs), 0) self.assertEqual(sqs[:10], []) try: sqs[4] self.fail() except IndexError: pass def test_dictionary_lookup(self): """ Ensure doing a dictionary lookup raises a TypeError so EmptySearchQuerySets can be used in templates. """ self.assertRaises(TypeError, lambda: self.esqs['count'])
def __init__(self, instance=None, data=empty, **kwargs): super(HaystackSerializer, self).__init__(instance, data, **kwargs) try: if not hasattr(self.Meta, "index_classes") and not hasattr( self.Meta, "serializers"): raise ImproperlyConfigured( "You must set either the 'index_classes' or 'serializers' " "attribute on the serializer Meta class.") except AttributeError: raise ImproperlyConfigured("%s must implement a Meta class." % self.__class__.__name__) if not self.instance: self.instance = EmptySearchQuerySet()
def get_search_queryset(self): """ Return the results for this search We only need the id because we directly load a cached template """ if self.query: keywords = self.parse_keywords(self.query) queryset = self.make_query(self.search_fields, keywords) queryset = queryset.models(self.model).only( 'id', 'get_absolute_url', 'modified') return queryset.result_class(self.result_class) else: return EmptySearchQuerySet()
class AldrynSearchView(FormMixin, ListView): template_name = 'aldryn_search/search_results.html' queryset = EmptySearchQuerySet() form_class = ModelSearchForm load_all = False searchqueryset = None paginate_by = 10 paginator_class = DiggPaginator def get_form_kwargs(self): kwargs = super(AldrynSearchView, self).get_form_kwargs() kwargs['load_all'] = self.load_all if self.searchqueryset is not None: kwargs['searchqueryset'] = self.searchqueryset return kwargs def get_form(self, form_class): data = self.request.GET if len(self.request.GET) else None return form_class(data, **self.get_form_kwargs()) def get_query(self, form): """ Returns the query provided by the user. Returns an empty string if the query is invalid. """ if form.is_valid(): return form.cleaned_data['q'] return '' def get(self, request, *args, **kwargs): self.form = self.get_form(self.get_form_class()) return super(AldrynSearchView, self).get(request, *args, **kwargs) def get_queryset(self): return self.form.search() def get_context_data(self, **kwargs): context = super(AldrynSearchView, self).get_context_data(**kwargs) context['query'] = self.get_query(self.form) context['form'] = self.form results = context['object_list'] if results and hasattr( results, 'query') and results.query.backend.include_spelling: context['suggestion'] = self.form.get_suggestion() return context
def setUp(self): super(EmptySearchQuerySetTestCase, self).setUp() self.esqs = EmptySearchQuerySet()
def search(request, template='search/search.html', load_all=True, form_class=ModelSearchForm, searchqueryset=None, extra_context=None, results_per_page=None): """ """ context = RequestContext(request) query = '' results = EmptySearchQuerySet() if request.GET.get('q'): form = form_class(request.GET, searchqueryset=searchqueryset, load_all=load_all) if form.is_valid(): query = form.cleaned_data['q'] results = form.search() context.update({'last_search': query}) # if return no result, try it again with autocomplete search word if results.count() == 0: results = SearchQuerySet().autocomplete(enfname=request.GET.get('q', '')) else: form = form_class(searchqueryset=searchqueryset, load_all=load_all) selected_facets_list = [] if request.GET.getlist('selected_facets'): for facet in request.GET.getlist('selected_facets'): if ":" not in facet: continue field, value = facet.split(":", 1) results = results.narrow(u'%s:"%s"' % (field, value)) # 生成页面的facet selected_facets_list.append(('&selected_facets='+facet, value)) selected_facets_context = list({ 'name': i[1], 'rm_selected_facet': ''.join(list(j[0] for j in selected_facets_list if j!=i))} for i in selected_facets_list) context.update({'selected_facets_context': selected_facets_context}) def facet_field_to_selector(sqs, name, context_name): try: fields = sqs.facet(name).facet_counts()['fields'][name] return {'name': context_name, 'exact_name': name, 'options': list({'context': i} for i in fields)} except: pass return None selectors = [] # 找出品牌的facet selectors.append(facet_field_to_selector(results, 'brand', '品牌')) # 找出品类的facet selectors.append(facet_field_to_selector(results, 'categ', '品类')) context.update({'selectors': selectors}) rm_invalid_result = [] for r in results: try: tmp = r._get_object() if tmp: rm_invalid_result.append(tmp) except: pass paginator = HXPaginator(rm_invalid_result, results_per_page or 40) page = int(request.GET.get('page', 1)) try: templates = paginator.page(page) except PageNotAnInteger: page = 1 except EmptyPage: page = paginator.num_pages context.update({ 'form': form, 'templates': templates, 'paginator': paginator, 'query': query, 'suggestion': None, }) if results.query.backend.include_spelling: context['suggestion'] = form.get_suggestion() if extra_context: context.update(extra_context) return TemplateResponse(request, template, context)
def search(request): """ Description: Handles requests from site's search bar Based off haystack.views.basic_search() Arguments: request: HttpRequest object Return: HttpResponse object showing search results with following additional details - query: search query - suggestion: backend-suggested search query Author: Nnoduka Eruchalu """ query = "" results = EmptySearchQuerySet() suggestion = False if request.GET.get("q"): form = SearchForm(request.GET, searchqueryset=None, load_all=True) if form.is_valid(): query = form.cleaned_data["q"] results = form.search() if results.query.backend.include_spelling: suggestion = form.get_suggestion() search_list = [r.object for r in results] paginator = Paginator(search_list, settings.RESULTS_PER_PAGE) page = request.GET.get("page") try: results = paginator.page(page) except PageNotAnInteger: # if page is not an integer, deliver first page. results = paginator.page(1) except EmptyPage: # if page is out of range (e.g. 999), deliver last page of results results = paginator.page(paginator.num_pages) if results.has_next(): next_page_num = results.next_page_number() else: next_page_num = 0 # way of indicating no more pages... 1 index'd helped! if results.has_previous(): prev_page_num = results.previous_page_number() else: prev_page_num = 0 results = results.object_list return render_to_response( "search/search.html", { "query": query, "suggestion": suggestion, "results": results, "next_page": next_page_num, "prev_page": prev_page_num, }, context_instance=RequestContext(request), )
def basic_search(request, template='search/search.html', load_all=True, form_class=ModelSearchForm, searchqueryset=None, context_class=RequestContext, extra_context=None, results_per_page=None, sort_by=[]): """ A more traditional view that also demonstrate an alternative way to use Haystack. Useful as an example of for basing heavily custom views off of. Also has the benefit of thread-safety, which the ``SearchView`` class may not be. Template:: ``search/search.html`` Context:: * form An instance of the ``form_class``. (default: ``ModelSearchForm``) * page The current page of search results. * paginator A paginator instance for the results. * query The query received by the form. """ query = '' results = EmptySearchQuerySet() try: del request.session['selected_facets'] except: pass if request.GET.get('q'): form = form_class(request.GET, searchqueryset=searchqueryset, load_all=load_all) if form.is_valid(): query = form.cleaned_data['q'] results = form.search() else: form = form_class(searchqueryset=searchqueryset, load_all=load_all) results = SearchQuerySet().all() selected_facets = request.GET.getlist('selected_facets') selected_date_facets = request.GET.getlist('selected_date_facets') selected_facets = FacetSet(facet_string_list=selected_facets, date_facet_string_list=selected_date_facets) request.session['selected_facets'] = selected_facets results = selected_facets.narrow(results) if not sort_by == ['tmp']: results = results.order_by(*sort_by) results = results.order_by('-score') if not template: return results count = results.count() paginator = Paginator(results, results_per_page or RESULTS_PER_PAGE) try: page = paginator.page(int(request.GET.get('page', 1))) except InvalidPage: raise Http404("No such page of results!") context = { 'form': form, 'page': page, 'paginator': paginator, 'query': query, 'suggestion': None, 'count': count, } if getattr(settings, 'HAYSTACK_INCLUDE_SPELLING', False): context['suggestion'] = form.get_suggestion() if extra_context: context.update(extra_context) return render_to_response(template, context, context_instance=context_class(request))
def catalogue_search(request, template='search/search.html', load_all=True, form_class=CatalogueSearchForm, searchqueryset=None, extra_context=None, results_per_page=None): """ A more traditional view that also demonstrate an alternative way to use Haystack. Useful as an example of for basing heavily custom views off of. Also has the benefit of thread-safety, which the ``SearchView`` class may not be. Template:: ``search/search.html`` Context:: * form An instance of the ``form_class``. (default: ``ModelSearchForm``) * page The current page of search results. * paginator A paginator instance for the results. * query The query received by the form. """ query = '' results = EmptySearchQuerySet() results_per_page = results_per_page or RESULTS_PER_PAGE if request.GET.get('q'): form = form_class(request.GET, searchqueryset=searchqueryset, load_all=load_all) if form.is_valid(): query = form.cleaned_data['q'] results = form.search() else: form = form_class(searchqueryset=searchqueryset, load_all=load_all) results = results.facet('categories').facet('country').facet('has_images').facet('global_region').facet('item_name') if form.is_valid(): results = filter_with_facet(form, results, 'item_name', 'item_name') results = filter_with_facet(form, results, 'category', 'categories') results = filter_with_facet(form, results, 'global_region', 'global_region') results = filter_with_facet(form, results, 'country', 'country') if form.cleaned_data['person']: sqs = SearchQuerySet() for p in form.cleaned_data['person'].split(): term = sqs.query.clean(p) results = results.narrow(u'people:"%s"' % term) if form.cleaned_data['has_images'] == True: results = results.narrow(u'has_images_exact:true') facets = results.facet_counts() if facets: # Prepare the form with all the available facets load_facets_into_form(form, facets, 'item_name', 'item_name') load_facets_into_form(form, facets, 'category', 'categories') load_facets_into_form(form, facets, 'global_region', 'global_region') load_facets_into_form(form, facets, 'country', 'country') # Append count of images into form appended_count = False for name, val in facets['fields']['has_images']: if name == 'true': form.fields['has_images'].label += ' (%s)' % val appended_count = True if not appended_count: form.fields['has_images'].label += ' (0)' results = results.order_by('registration_number') paginator = Paginator(results, results_per_page) try: page = paginator.page(int(request.GET.get('page', 1))) except InvalidPage: raise Http404("No such page of results!") context = { 'form': form, 'page': page, 'paginator': paginator, 'query': query, 'suggestion': None, 'facets': facets, } # Store query for paging through results on item detail page if form.is_valid(): request.session['search_query'] = form.cleaned_data # Access the first result to prevent ZeroDivisionError if results: results[0] request.session['search_results'] = results request.session['search_results_per_page'] = results_per_page if getattr(settings, 'HAYSTACK_INCLUDE_SPELLING', False): context['suggestion'] = form.get_suggestion() if extra_context: context.update(extra_context) return render(request, template, context)