def create_queryset(user): # ideally we'd do it this way, and not mention specific models here # (instead doing visibility checking in their respective search_index.py files), # but there's no way to pass a user into serach_index.load_all_queryset. yet. # # return RelatedSearchQuerySet() qs = RelatedSearchQuerySet().load_all_queryset(GroupTopic, GroupTopic.objects.visible(user)) qs = qs.load_all_queryset(Whiteboard, Whiteboard.objects.visible(user)) qs = qs.load_all_queryset(Event, Event.objects.visible(user)) return qs
def _haystack_search(self, content, queryset, max_results, partial, using): from haystack.query import RelatedSearchQuerySet from haystack.inputs import AutoQuery if content.strip() == '': return RelatedSearchQuerySet().none() # Limit to the model bound to this manager, e.g. DataConcept. # `load_all` ensures a single database hit when loading the objects # that match sqs = RelatedSearchQuerySet().models(self.model).load_all() # If a non-default backend is being used, set which backend is to # be used. if using is not None: sqs = sqs.using(using) if partial: # Autocomplete only works with N-gram fields. sqs = sqs.autocomplete(text_auto=content) else: # Automatically handles advanced search syntax for negations # and quoted strings. sqs = sqs.filter(text=AutoQuery(content)) if queryset is not None: sqs = sqs.load_all_queryset(self.model, queryset) if max_results: return sqs[:max_results] return sqs
def _haystack_search(self, content, queryset, max_results, partial, using): from haystack.query import RelatedSearchQuerySet from haystack.inputs import AutoQuery if content.strip() == '': return RelatedSearchQuerySet().none() # Limit to the model bound to this manager, e.g. DataConcept. # `load_all` ensures a single database hit when loading the objects # that match sqs = RelatedSearchQuerySet().models(self.model).load_all() # If a non-default backend is being used, set which backend is to # be used. if using is not None: sqs = sqs.using(using) if partial: # Autocomplete only works with N-gram fields. sqs = sqs.autocomplete(text_auto=content) else: # Automatically handles advanced search syntax for negations # and quoted strings. sqs = sqs.filter(text=AutoQuery(content)) if queryset is not None: sqs = sqs.load_all_queryset(self.model, queryset) if max_results: return sqs[:max_results] return sqs
def search(self, content, queryset=None, max_results=10): from haystack.query import RelatedSearchQuerySet sqs = RelatedSearchQuerySet().models(self.model).load_all()\ .auto_query(content) if queryset is not None: sqs = sqs.load_all_queryset(self.model, queryset) if max_results: return sqs[:max_results] return sqs
def create_queryset(user): # ideally we'd do it this way, and not mention specific models here # (instead doing visibility checking in their respective search_index.py files), # but there's no way to pass a user into serach_index.load_all_queryset. yet. # # return RelatedSearchQuerySet() qs = RelatedSearchQuerySet().load_all_queryset( GroupTopic, GroupTopic.objects.visible(user)) qs = qs.load_all_queryset(Whiteboard, Whiteboard.objects.visible(user)) qs = qs.load_all_queryset(Event, Event.objects.visible(user)) # TODO: centralize this somewhere? execlist = get_object_or_none(Community, slug='exec') if execlist and execlist.user_is_member(user, True): qs = qs.load_all_queryset(Activity, Activity.objects.all()) else: qs = qs.load_all_queryset(Activity, Activity.objects.none()) return qs
def create_queryset(user): # ideally we'd do it this way, and not mention specific models here # (instead doing visibility checking in their respective search_index.py files), # but there's no way to pass a user into serach_index.load_all_queryset. yet. # # return RelatedSearchQuerySet() qs = RelatedSearchQuerySet().load_all_queryset(GroupTopic, GroupTopic.objects.visible(user)) qs = qs.load_all_queryset(Whiteboard, Whiteboard.objects.visible(user)) qs = qs.load_all_queryset(Event, Event.objects.visible(user)) qs = qs.load_all_queryset(Term, Term.objects.all()) # TODO: centralize this somewhere? execlist = get_object_or_none(Community, slug='exec') if execlist and execlist.user_is_member(user, True): qs = qs.load_all_queryset(Activity, Activity.objects.all()) else: qs = qs.load_all_queryset(Activity, Activity.objects.none()) return qs
def research_list(request, study_type="all", template="participant/research_list.html", extra_context=None): if request.method == "POST": q = request.POST.get("q", "") research_list = RelatedSearchQuerySet().filter(context=AutoQuery(q)).load_all() if study_type == "ol": research_list = research_list.load_all_queryset( Research, Research.objects.filter(is_on_web=True, is_publish=True, is_complete=False) .exclude(participantresearch__participant=request.user) .exclude(scientistresearch__scientist=request.user), ) elif study_type == "nol" or study_type == "nol_map": research_list = research_list.load_all_queryset( Research, Research.objects.filter(is_on_web=False, is_publish=True, is_complete=False) .exclude(participantresearch__participant=request.user) .exclude(scientistresearch__scientist=request.user), ) elif study_type == "all": research_list = research_list.load_all_queryset( Research, Research.objects.filter(is_publish=True, is_complete=False) .exclude(participantresearch__participant=request.user) .exclude(scientistresearch__scientist=request.user), ) paginator = get_page(request, research_list, 15) context = {"study_type": study_type, "paginator": paginator, "research_list": research_list, "q": q} else: research_list = research_randomize(request, study_type) paginator = get_page(request, research_list, 15) context = {"study_type": study_type, "paginator": paginator, "research_list": research_list, "q": ""} if extra_context: context.update(extra_context) return render_to_response(template, context, context_instance=RequestContext(request))
def get_results(self, request): if not SEARCH_VAR in request.GET: return super(AllChangeList, self).get_results(request) # Note that pagination is 0-based, not 1-based. sqs = RelatedSearchQuerySet().models(self.model).auto_query( request.GET[SEARCH_VAR]).load_all() if not request.user.is_superuser: result = self.model.objects.distinct().filter( Q(owners=request.user) | Q(editor_groups__name__in=request.user.groups.values_list( 'name', flat=True))) else: result = self.model.objects.distinct() if 'storage_object__publication_status__exact' in request.GET: result = result.filter( storage_object__publication_status__exact=request. GET["storage_object__publication_status__exact"]) sqs = sqs.load_all_queryset(self.model, result) paginator = Paginator(sqs, self.list_per_page) # Fixed bug for pagination, count full_result_count full_result_count = 0 for sq in sqs: full_result_count += 1 result_count = paginator.count # Get the number of objects, with admin filters applied. can_show_all = result_count <= list_max_show_all(self) multi_page = result_count > self.list_per_page # Get the list of objects to display on this page. try: result_list = paginator.page(self.page_num + 1).object_list # Grab just the Django models, since that's what everything else is # expecting. result_list = [result.object for result in result_list] except InvalidPage: result_list = () self.result_count = result_count self.full_result_count = full_result_count self.result_list = result_list self.can_show_all = can_show_all self.multi_page = multi_page self.paginator = paginator
def get_results(self, request): if not SEARCH_VAR in request.GET: return super(AllChangeList, self).get_results(request) # Note that pagination is 0-based, not 1-based. sqs = RelatedSearchQuerySet().models(self.model).auto_query(request.GET[SEARCH_VAR]).load_all() if not request.user.is_superuser: result = self.model.objects.distinct().filter(Q(owners=request.user) | Q(editor_groups__name__in= request.user.groups.values_list('name', flat=True))) else: result = self.model.objects.distinct() if 'storage_object__publication_status__exact' in request.GET: result = result.filter(storage_object__publication_status__exact=request.GET["storage_object__publication_status__exact"]) sqs = sqs.load_all_queryset(self.model, result) paginator = Paginator(sqs, self.list_per_page) # Fixed bug for pagination, count full_result_count full_result_count = 0 for sq in sqs: full_result_count += 1 result_count = paginator.count # Get the number of objects, with admin filters applied. can_show_all = result_count <= list_max_show_all(self) multi_page = result_count > self.list_per_page # Get the list of objects to display on this page. try: result_list = paginator.page(self.page_num+1).object_list # Grab just the Django models, since that's what everything else is # expecting. result_list = [result.object for result in result_list] except InvalidPage: result_list = () self.result_count = result_count self.full_result_count = full_result_count self.result_list = result_list self.can_show_all = can_show_all self.multi_page = multi_page self.paginator = paginator
def get_context_data(self, **kwargs): context = super(SAQuestionIndex, self).get_context_data(**kwargs) context['ministers'] = [] ministers = Section.objects.filter(parent__heading='Questions') ministers = sorted(ministers, key=questions_section_sort_key) for minister in ministers: context['ministers'].append({ 'title': minister.title.replace('Questions asked to the ', ''), 'slug': minister.slug }) context['orderby'] = 'recentanswers' context['minister'] = 'all' context['q'] = '' #set filter values for key in ('orderby', 'minister', 'q'): if key in self.request.GET: context[key] = self.request.GET[key] if not context['orderby'] in ['recentquestions', 'recentanswers']: context['orderby'] = 'recentquestions' search_result_sections = [] if context['q'] != '': #using a RelatedSearchQuerySet seems to result in fewer #queries, although the same results can be achieved with a #SearchQuerySet query = RelatedSearchQuerySet().models(Speech) query = query.filter( tags__name__in=['question', 'answer'], content=AutoQuery(context['q']), ).load_all() all_speeches = Speech.objects.all().filter( tags__name__in=['question', 'answer']) if context['minister'] != 'all': all_speeches = all_speeches.filter( section__parent__slug=context['minister']) query = query.load_all_queryset(Speech, all_speeches) for result in query: search_result_sections.append(result.object.section.id) sections = Section \ .objects \ .filter( parent__parent__heading='Questions' ) \ .select_related('parent') \ .prefetch_related('speech_set') \ .annotate( earliest_date=Min('speech__start_date'), smallest_id=Min('speech__id'), number_speeches=Count('speech'), latest_date=Max('speech__start_date'), ) if context['minister'] != 'all': sections = sections.filter(parent__slug=context['minister']) if len(search_result_sections) > 0: sections = sections.filter(id__in=search_result_sections) if context['orderby'] == 'recentanswers': sections = sections.filter(number_speeches__gt=1).order_by( '-latest_date', '-smallest_id') else: sections = sections.order_by('-earliest_date', '-smallest_id') paginator = Paginator(sections, 10) page = self.request.GET.get('page') try: sections = paginator.page(page) except PageNotAnInteger: sections = paginator.page(1) except EmptyPage: sections = paginator.page(paginator.num_pages) context['paginator'] = sections #format questions and answers for the template questions = [] for section in sections: question = section.speech_set.all()[0] question.questionto = section.parent.heading.replace( 'Questions asked to the ', '') question.questionto_slug = section.parent.slug #assume if there is more than one speech that the question is answered if len(section.speech_set.all()) > 1: question.answer = section \ .speech_set \ .all()[len(section.speech_set.all()) - 1] #extract the actual reply from the reply text (replies #often include the original question and other text, #such as a letterhead) text = question.answer.text.split('REPLY') if len(text) > 1: question.answer.text = text[len(text) - 1] if question.answer.text[0] == ':': question.answer.text = question.answer.text[1:] questions.append(question) context['speeches'] = questions return context
def plus_search(tags, search, search_types, order=None, in_group=None, extra_filter=None): items = get_resources_for_tag_intersection(tags) q = None for typ, info in search_types: if info[0]: typ_items = Q(**info[0]) if info[1]: typ_items = typ_items & ~Q(**info[1]) elif info[1]: typ_items = ~Q(**info[1]) if not q: q = typ_items else: q = q | typ_items if extra_filter: q = q & Q(**extra_filter) if q: items = items.filter(q) included = None for obj_class, included_filter in object_type_filters.items(): objs = obj_class.objects.filter(**included_filter) included_search = { 'content_type__model': obj_class.__name__.lower(), 'object_id__in': objs } if not included: included = Q(**included_search) included = included | Q(**included_search) items = items.filter(included) if in_group: # this should be implemented using the code just above and an external search filter arg page_ids = WikiPage.objects.filter(in_agent=in_group, stub=False) wikipages = Q(**{ 'content_type__model': 'wikipage', 'object_id__in': page_ids }) resource_ids = Resource.objects.filter(in_agent=in_group, stub=False) resources = Q(**{ 'content_type__model': 'resource', 'object_id__in': resource_ids }) q = resources | wikipages items = items.filter(q) results_map = {} tag_intersection = [] if search: results = RelatedSearchQuerySet().auto_query(search) results_map = {} if results: all_results = results.load_all_queryset(GenericReference, items) if order == 'relevance': all_results = all_results.load_all( ) # this bit is quite evil and makes things really inefficient for large searches # a better approach would be to get all the ids directly from the fulltext index and use them as a filter for GenericReferences results_map['All'] = [item.object for item in all_results ] #we really really shouldn't do this items_len = len(results_map['All']) else: search_results = [result.pk for result in all_results] results_map['All'] = items.filter( id__in=search_results).order_by(order) items_len = results_map['All'].count() else: results_map = {'All': EmptySearchQuerySet()} items_len = 0 else: if items: items = items.order_by('creator') items_len = items.count() results_map['All'] = items else: items_len = 0 results_map = {'All': EmptySearchQuerySet()} if order == 'modified': results_map['All'] = results_map['All'].order_by('-' + order) elif order == 'display_name': results_map['All'] = results_map['All'].order_by(order) if 'All' in results_map: tag_intersection = get_intersecting_tags(results_map['All'], n=15) if len(search_types) > 1: for typ, info in search_types: if info[0]: typ_items = items.filter(**info[0]) if info[1]: typ_items = items.exclude(**info[1]) if search and results and order == 'relevance': # why do this again when we could just separate results using python typ_items = all_results.load_all_queryset( GenericReference, typ_items) typ_items = [item.object for item in typ_items ] #we really really shouldn't do this if typ_items: results_map[typ] = typ_items else: results_map = {'All': EmptySearchQuerySet()} search_type_data = [] for typ, data in search_types: if results_map.has_key(typ): try: type_len = results_map[typ].count() except TypeError: type_len = len(results_map[typ]) search_type_data.append((typ, data[2], results_map[typ], type_len)) return { 'All': results_map['All'], 'items_len': items_len, 'search_types': search_type_data, 'tag_intersection': tag_intersection }
def plus_search(tags, search, search_types, order=None, in_group=None, extra_filter=None): items = get_resources_for_tag_intersection(tags) q = None for typ, info in search_types: if info[0]: typ_items = Q(**info[0]) if info[1]: typ_items = typ_items & ~Q(**info[1]) elif info[1]: typ_items = ~Q(**info[1]) if not q: q = typ_items else: q = q | typ_items if extra_filter: q = q & Q(**extra_filter) if q: items = items.filter(q) included = None for obj_class, included_filter in object_type_filters.items(): objs = obj_class.objects.filter(**included_filter) included_search = {'content_type__model':obj_class.__name__.lower(), 'object_id__in':objs} if not included: included = Q(**included_search) included = included | Q(**included_search) items = items.filter(included) if in_group: # this should be implemented using the code just above and an external search filter arg page_ids = WikiPage.objects.filter(in_agent=in_group, stub=False) wikipages = Q(**{'content_type__model':'wikipage', 'object_id__in':page_ids}) resource_ids = Resource.objects.filter(in_agent=in_group, stub=False) resources = Q(**{'content_type__model':'resource', 'object_id__in':resource_ids}) q = resources | wikipages items = items.filter(q) results_map = {} tag_intersection = [] if search: results = RelatedSearchQuerySet().auto_query(search) results_map = {} if results: all_results = results.load_all_queryset(GenericReference, items) if order == 'relevance': all_results = all_results.load_all() # this bit is quite evil and makes things really inefficient for large searches # a better approach would be to get all the ids directly from the fulltext index and use them as a filter for GenericReferences results_map['All'] = [item.object for item in all_results] #we really really shouldn't do this items_len = len(results_map['All']) else: search_results = [result.pk for result in all_results] results_map['All'] = items.filter(id__in=search_results).order_by(order) items_len = results_map['All'].count() else: results_map = {'All':EmptySearchQuerySet()} items_len = 0 else: if items: items = items.order_by('creator') items_len = items.count() results_map['All'] = items else: items_len = 0 results_map = {'All':EmptySearchQuerySet()} if order == 'modified': results_map['All'] = results_map['All'].order_by('-' + order) elif order == 'display_name': results_map['All'] = results_map['All'].order_by(order) if 'All' in results_map: tag_intersection = get_intersecting_tags(results_map['All'], n=15) if len(search_types) > 1: for typ, info in search_types: if info[0]: typ_items = items.filter(**info[0]) if info[1]: typ_items = items.exclude(**info[1]) if search and results and order == 'relevance': # why do this again when we could just separate results using python typ_items = all_results.load_all_queryset(GenericReference, typ_items) typ_items = [item.object for item in typ_items] #we really really shouldn't do this if typ_items: results_map[typ] = typ_items else: results_map = {'All':EmptySearchQuerySet()} search_type_data = [] for typ, data in search_types: if results_map.has_key(typ): try: type_len = results_map[typ].count() except TypeError: type_len = len(results_map[typ]) search_type_data.append((typ, data[2], results_map[typ], type_len)) return {'All':results_map['All'], 'items_len':items_len, 'search_types':search_type_data, 'tag_intersection':tag_intersection}
def get_context_data(self, **kwargs): context = super(SAQuestionIndex, self).get_context_data(**kwargs) context['ministers'] = [] ministers = Section.objects.filter(parent__heading='Questions') ministers = sorted(ministers, key=questions_section_sort_key) for minister in ministers: context['ministers'].append({ 'title': minister.title.replace('Questions asked to the ', ''), 'slug': minister.slug }) context['orderby'] = 'recentanswers' context['minister'] = 'all' context['q'] = '' #set filter values for key in ('orderby', 'minister', 'q'): if key in self.request.GET: context[key] = self.request.GET[key] if not context['orderby'] in ['recentquestions', 'recentanswers']: context['orderby'] = 'recentquestions' search_result_sections = [] if context['q'] != '': #using a RelatedSearchQuerySet seems to result in fewer #queries, although the same results can be achieved with a #SearchQuerySet query = RelatedSearchQuerySet().models(Speech) query = query.filter( tags__name__in=['question', 'answer'], content=AutoQuery(context['q']), ).load_all() all_speeches = Speech.objects.all().filter( tags__name__in=['question', 'answer']) if context['minister'] != 'all': all_speeches = all_speeches.filter( section__parent__slug=context['minister'] ) query = query.load_all_queryset(Speech, all_speeches) for result in query: search_result_sections.append(result.object.section.id) sections = Section \ .objects \ .filter( parent__parent__heading='Questions' ) \ .select_related('parent__heading') \ .prefetch_related('speech_set') \ .annotate( earliest_date=Min('speech__start_date'), smallest_id=Min('speech__id'), number_speeches=Count('speech'), latest_date=Max('speech__start_date'), ) if context['minister'] != 'all': sections = sections.filter(parent__slug=context['minister']) if len(search_result_sections) > 0: sections = sections.filter(id__in=search_result_sections) if context['orderby'] == 'recentanswers': sections = sections.filter(number_speeches__gt=1).order_by( '-latest_date', '-smallest_id' ) else: sections = sections.order_by( '-earliest_date', '-smallest_id' ) paginator = Paginator(sections, 10) page = self.request.GET.get('page') try: sections = paginator.page(page) except PageNotAnInteger: sections = paginator.page(1) except EmptyPage: sections = paginator.page(paginator.num_pages) context['paginator'] = sections #format questions and answers for the template questions = [] for section in sections: question = section.speech_set.all()[0] question.questionto = section.parent.heading.replace( 'Questions asked to the ', '') question.questionto_slug = section.parent.slug #assume if there is more than one speech that the question is answered if len(section.speech_set.all()) > 1: question.answer = section \ .speech_set \ .all()[len(section.speech_set.all()) - 1] #extract the actual reply from the reply text (replies #often include the original question and other text, #such as a letterhead) text = question.answer.text.split('REPLY') if len(text) > 1: question.answer.text = text[len(text) - 1] if question.answer.text[0] == ':': question.answer.text = question.answer.text[1:] questions.append(question) context['speeches'] = questions return context