Example #1
0
    def prepare_template(self, obj):
        """
        Flattens an object for indexing.

        This loads a template
        (``search/indexes/{app_label}/{model_name}_{field_name}.txt``) and
        returns the result of rendering that template. ``object`` will be in
        its context.
        """
        if self.instance_name is None and self.template_name is None:
            raise SearchFieldError(
                "This field requires either its instance_name variable to be populated or an explicit template_name in order to load the correct template."
            )

        if self.template_name is not None:
            template_names = self.template_name

            if not isinstance(template_names, (list, tuple)):
                template_names = [template_names]
        else:
            app_label, model_name = get_model_ct_tuple(obj)
            template_names = ["search/indexes/%s/%s_%s.txt" % (app_label, model_name, self.instance_name)]

        t = loader.select_template(template_names)
        return t.render(Context({"object": obj}))
Example #2
0
    def prepare_template(self, obj):
        """
        Flattens an object for indexing.

        This loads a template
        (``search/indexes/{app_label}/{model_name}_{field_name}.txt``) and
        returns the result of rendering that template. ``object`` will be in
        its context.
        """
        if self.instance_name is None and self.template_name is None:
            raise SearchFieldError(
                "This field requires either its instance_name variable to be populated or an explicit template_name in order to load the correct template."
            )

        if self.template_name is not None:
            template_names = self.template_name

            if not isinstance(template_names, (list, tuple)):
                template_names = [template_names]
        else:
            app_label, model_name = get_model_ct_tuple(obj)
            template_names = [
                'search/indexes/%s/%s_%s.txt' %
                (app_label, model_name, self.instance_name)
            ]

        t = loader.select_template(template_names)
        return t.render({'object': obj})
Example #3
0
    def prepare_template(self, obj):
        app_label, model_name = get_model_ct_tuple(obj)
        template_names = ['search/indexes/%s/%s_%s.txt' %
                          (app_label, model_name, self.instance_name)]

        t = loader.select_template(template_names)

        return t.render({'object': obj,
                         'extracted': self.extract_data(obj)})
Example #4
0
    def search(self, query_string, **kwargs):
        hits = 0
        results = []
        result_class = SearchResult
        models = (connections[
            self.connection_alias].get_unified_index().get_indexed_models())

        if kwargs.get("result_class"):
            result_class = kwargs["result_class"]

        if kwargs.get("models"):
            models = kwargs["models"]

        if query_string:
            for model in models:
                if query_string == "*":
                    qs = model.objects.all()
                else:
                    for term in query_string.split():
                        queries = []

                        for field in model._meta.fields:
                            if hasattr(field, "related"):
                                continue

                            if not field.get_internal_type() in (
                                    "TextField",
                                    "CharField",
                                    "SlugField",
                            ):
                                continue

                            queries.append(
                                Q(**{"%s__icontains" % field.name: term}))

                        if queries:
                            qs = model.objects.filter(
                                reduce(lambda x, y: x | y, queries))
                        else:
                            qs = []

                hits += len(qs)

                for match in qs:
                    match.__dict__.pop("score", None)
                    app_label, model_name = get_model_ct_tuple(match)
                    result = result_class(app_label, model_name, match.pk, 0,
                                          **match.__dict__)
                    # For efficiency.
                    result._model = match.__class__
                    result._object = match
                    results.append(result)

        return {
            "results": results[kwargs.get('start_offset', 0):],
            "hits": hits
        }
Example #5
0
    def search(self, query_string, **kwargs):
        hits = 0
        results = []
        result_class = SearchResult
        models = (
            connections[self.connection_alias].get_unified_index().get_indexed_models()
        )

        if kwargs.get("result_class"):
            result_class = kwargs["result_class"]

        if kwargs.get("models"):
            models = kwargs["models"]

        if query_string:
            for model in models:
                if query_string == "*":
                    qs = model.objects.all()
                else:
                    for term in query_string.split():
                        queries = []

                        for field in model._meta.fields:
                            if hasattr(field, "related"):
                                continue

                            if not field.get_internal_type() in (
                                "TextField",
                                "CharField",
                                "SlugField",
                            ):
                                continue

                            queries.append(Q(**{"%s__icontains" % field.name: term}))

                        if queries:
                            qs = model.objects.filter(
                                six.moves.reduce(lambda x, y: x | y, queries)
                            )
                        else:
                            qs = []

                hits += len(qs)

                for match in qs:
                    match.__dict__.pop("score", None)
                    app_label, model_name = get_model_ct_tuple(match)
                    result = result_class(
                        app_label, model_name, match.pk, 0, **match.__dict__
                    )
                    # For efficiency.
                    result._model = match.__class__
                    result._object = match
                    results.append(result)

        return {"results": results, "hits": hits}
Example #6
0
    def search(self, query_string, **kwargs):
        hits = 0
        results = []
        result_class = SearchResult
        models = connections[
            self.connection_alias].get_unified_index().get_indexed_models()

        if kwargs.get('result_class'):
            result_class = kwargs['result_class']

        if kwargs.get('models'):
            models = kwargs['models']

        if query_string:
            for model in models:
                if query_string == '*':
                    qs = model.objects.all()
                else:
                    for term in query_string.split():
                        queries = []

                        for field in model._meta.fields:
                            if hasattr(field, 'related'):
                                continue

                            if not field.get_internal_type() in (
                                    'TextField', 'CharField', 'SlugField'):
                                continue

                            queries.append(
                                Q(**{'%s__icontains' % field.name: term}))

                        qs = model.objects.filter(
                            six.moves.reduce(
                                lambda x, y: x | y,
                                queries)) if queries else qs.none()

                hits += len(qs)

                for match in qs:
                    match.__dict__.pop('score', None)
                    app_label, model_name = get_model_ct_tuple(match)
                    result = result_class(app_label, model_name, match.pk, 0,
                                          **match.__dict__)
                    # For efficiency.
                    result._model = match.__class__
                    result._object = match
                    results.append(result)

        return {
            'results': results,
            'hits': hits,
        }
Example #7
0
    def search(self, query_string, **kwargs):
        hits = 0
        results = []
        result_class = SearchResult
        models = connections[self.connection_alias].get_unified_index().get_indexed_models()

        if kwargs.get('result_class'):
            result_class = kwargs['result_class']

        if kwargs.get('models'):
            models = kwargs['models']

        if query_string:
            for model in models:
                if query_string == '*':
                    qs = model.objects.all()
                else:
                    for term in query_string.split():
                        queries = []

                        for field in model._meta.fields:
                            if hasattr(field, 'related'):
                                continue

                            if not field.get_internal_type() in ('TextField', 'CharField', 'SlugField'):
                                continue

                            queries.append(Q(**{'%s__icontains' % field.name: term}))

                        qs = model.objects.filter(six.moves.reduce(lambda x, y: x | y, queries))

                hits += len(qs)

                for match in qs:
                    match.__dict__.pop('score', None)
                    app_label, model_name = get_model_ct_tuple(match)
                    result = result_class(app_label, model_name, match.pk, 0, **match.__dict__)
                    # For efficiency.
                    result._model = match.__class__
                    result._object = match
                    results.append(result)

        return {
            'results': results,
            'hits': hits,
        }
Example #8
0
    def changelist_view(self, request, extra_context=None):
        if not self.has_change_permission(request, None):
            raise PermissionDenied

        if not SEARCH_VAR in request.GET:
            # Do the usual song and dance.
            return super(SearchModelAdminMixin, self).changelist_view(request, extra_context)

        # Do a search of just this model and populate a Changelist with the
        # returned bits.
        if not self.model in connections[self.haystack_connection].get_unified_index().get_indexed_models():
            # Oops. That model isn't being indexed. Return the usual
            # behavior instead.
            return super(SearchModelAdminMixin, self).changelist_view(request, extra_context)

        # So. Much. Boilerplate.
        # Why copy-paste a few lines when you can copy-paste TONS of lines?
        list_display = list(self.list_display)

        kwargs = {
            "haystack_connection": self.haystack_connection,
            "request": request,
            "model": self.model,
            "list_display": list_display,
            "list_display_links": self.list_display_links,
            "list_filter": self.list_filter,
            "date_hierarchy": self.date_hierarchy,
            "search_fields": self.search_fields,
            "list_select_related": self.list_select_related,
            "list_per_page": self.list_per_page,
            "list_editable": self.list_editable,
            "model_admin": self,
        }

        # Django 1.4 compatibility.
        if hasattr(self, "list_max_show_all"):
            kwargs["list_max_show_all"] = self.list_max_show_all

        changelist = SearchChangeList(**kwargs)
        formset = changelist.formset = None
        media = self.media

        # Build the action form and populate it with available actions.
        # Check actions to see if any are available on this changelist
        actions = self.get_actions(request)
        if actions:
            action_form = self.action_form(auto_id=None)
            action_form.fields["action"].choices = self.get_action_choices(request)
        else:
            action_form = None

        selection_note = ungettext("0 of %(count)d selected", "of %(count)d selected", len(changelist.result_list))
        selection_note_all = ungettext(
            "%(total_count)s selected", "All %(total_count)s selected", changelist.result_count
        )

        context = {
            "module_name": force_text(self.model._meta.verbose_name_plural),
            "selection_note": selection_note % {"count": len(changelist.result_list)},
            "selection_note_all": selection_note_all % {"total_count": changelist.result_count},
            "title": changelist.title,
            "is_popup": changelist.is_popup,
            "cl": changelist,
            "media": media,
            "has_add_permission": self.has_add_permission(request),
            # More Django 1.4 compatibility
            "root_path": getattr(self.admin_site, "root_path", None),
            "app_label": self.model._meta.app_label,
            "action_form": action_form,
            "actions_on_top": self.actions_on_top,
            "actions_on_bottom": self.actions_on_bottom,
            "actions_selection_counter": getattr(self, "actions_selection_counter", 0),
        }
        context.update(extra_context or {})
        context_instance = template.RequestContext(request, current_app=self.admin_site.name)
        app_name, model_name = get_model_ct_tuple(self.model)
        return render_to_response(
            self.change_list_template
            or [
                "admin/%s/%s/change_list.html" % (app_name, model_name),
                "admin/%s/change_list.html" % app_name,
                "admin/change_list.html",
            ],
            context,
            context_instance=context_instance,
        )
Example #9
0
    def changelist_view(self, request, extra_context=None):
        if not self.has_change_permission(request, None):
            raise PermissionDenied

        if SEARCH_VAR not in request.GET:
            # Do the usual song and dance.
            return super().changelist_view(request, extra_context)

        # Do a search of just this model and populate a Changelist with the
        # returned bits.
        indexed_models = (
            connections[self.haystack_connection]
            .get_unified_index()
            .get_indexed_models()
        )

        if self.model not in indexed_models:
            # Oops. That model isn't being indexed. Return the usual
            # behavior instead.
            return super().changelist_view(request, extra_context)

        # So. Much. Boilerplate.
        # Why copy-paste a few lines when you can copy-paste TONS of lines?
        list_display = list(self.list_display)

        kwargs = {
            "haystack_connection": self.haystack_connection,
            "request": request,
            "model": self.model,
            "list_display": list_display,
            "list_display_links": self.list_display_links,
            "list_filter": self.list_filter,
            "date_hierarchy": self.date_hierarchy,
            "search_fields": self.search_fields,
            "list_select_related": self.list_select_related,
            "list_per_page": self.list_per_page,
            "list_editable": self.list_editable,
            "list_max_show_all": self.list_max_show_all,
            "model_admin": self,
        }
        if hasattr(self, "get_sortable_by"):  # Django 2.1+
            kwargs["sortable_by"] = self.get_sortable_by(request)
        changelist = SearchChangeList(**kwargs)
        changelist.formset = None
        media = self.media

        # Build the action form and populate it with available actions.
        # Check actions to see if any are available on this changelist
        actions = self.get_actions(request)
        if actions:
            action_form = self.action_form(auto_id=None)
            action_form.fields["action"].choices = self.get_action_choices(request)
        else:
            action_form = None

        selection_note = ungettext(
            "0 of %(count)d selected",
            "of %(count)d selected",
            len(changelist.result_list),
        )
        selection_note_all = ungettext(
            "%(total_count)s selected",
            "All %(total_count)s selected",
            changelist.result_count,
        )

        context = {
            "module_name": force_str(self.model._meta.verbose_name_plural),
            "selection_note": selection_note % {"count": len(changelist.result_list)},
            "selection_note_all": selection_note_all
            % {"total_count": changelist.result_count},
            "title": changelist.title,
            "is_popup": changelist.is_popup,
            "cl": changelist,
            "media": media,
            "has_add_permission": self.has_add_permission(request),
            "opts": changelist.opts,
            "app_label": self.model._meta.app_label,
            "action_form": action_form,
            "actions_on_top": self.actions_on_top,
            "actions_on_bottom": self.actions_on_bottom,
            "actions_selection_counter": getattr(self, "actions_selection_counter", 0),
        }
        context.update(extra_context or {})
        request.current_app = self.admin_site.name
        app_name, model_name = get_model_ct_tuple(self.model)
        return render(
            request,
            self.change_list_template
            or [
                "admin/%s/%s/change_list.html" % (app_name, model_name),
                "admin/%s/change_list.html" % app_name,
                "admin/change_list.html",
            ],
            context,
        )
Example #10
0
    def changelist_view(self, request, extra_context=None):
        if not self.has_change_permission(request, None):
            raise PermissionDenied

        if not SEARCH_VAR in request.GET:
            # Do the usual song and dance.
            return super(SearchModelAdminMixin, self).changelist_view(request, extra_context)

        # Do a search of just this model and populate a Changelist with the
        # returned bits.
        if not self.model in connections[self.haystack_connection].get_unified_index().get_indexed_models():
            # Oops. That model isn't being indexed. Return the usual
            # behavior instead.
            return super(SearchModelAdminMixin, self).changelist_view(request, extra_context)

        # So. Much. Boilerplate.
        # Why copy-paste a few lines when you can copy-paste TONS of lines?
        list_display = list(self.list_display)

        kwargs = {
            'haystack_connection': self.haystack_connection,
            'request': request,
            'model': self.model,
            'list_display': list_display,
            'list_display_links': self.list_display_links,
            'list_filter': self.list_filter,
            'date_hierarchy': self.date_hierarchy,
            'search_fields': self.search_fields,
            'list_select_related': self.list_select_related,
            'list_per_page': self.list_per_page,
            'list_editable': self.list_editable,
            'model_admin': self
        }

        # Django 1.4 compatibility.
        if hasattr(self, 'list_max_show_all'):
            kwargs['list_max_show_all'] = self.list_max_show_all

        changelist = SearchChangeList(**kwargs)
        formset = changelist.formset = None
        media = self.media

        # Build the action form and populate it with available actions.
        # Check actions to see if any are available on this changelist
        actions = self.get_actions(request)
        if actions:
            action_form = self.action_form(auto_id=None)
            action_form.fields['action'].choices = self.get_action_choices(request)
        else:
            action_form = None

        selection_note = ungettext('0 of %(count)d selected',
            'of %(count)d selected', len(changelist.result_list))
        selection_note_all = ungettext('%(total_count)s selected',
            'All %(total_count)s selected', changelist.result_count)

        context = {
            'module_name': force_text(self.model._meta.verbose_name_plural),
            'selection_note': selection_note % {'count': len(changelist.result_list)},
            'selection_note_all': selection_note_all % {'total_count': changelist.result_count},
            'title': changelist.title,
            'is_popup': changelist.is_popup,
            'cl': changelist,
            'media': media,
            'has_add_permission': self.has_add_permission(request),
            # More Django 1.4 compatibility
            'root_path': getattr(self.admin_site, 'root_path', None),
            'app_label': self.model._meta.app_label,
            'action_form': action_form,
            'actions_on_top': self.actions_on_top,
            'actions_on_bottom': self.actions_on_bottom,
            'actions_selection_counter': getattr(self, 'actions_selection_counter', 0),
        }
        context.update(extra_context or {})
        context_instance = template.RequestContext(request, current_app=self.admin_site.name)
        app_name, model_name = get_model_ct_tuple(self.model)
        return render_to_response(self.change_list_template or [
            'admin/%s/%s/change_list.html' % (app_name, model_name),
            'admin/%s/change_list.html' % app_name,
            'admin/change_list.html'
        ], context, context_instance=context_instance)
Example #11
0
    def changelist_view(self, request, extra_context=None):
        if not self.has_change_permission(request, None):
            raise PermissionDenied

        list_filter = list(InternalSearchAdminSetting.list_filter)
        list_display = list(InternalSearchAdminSetting.list_display)

        model_meta = request.GET.get('type')
        if model_meta:
            config_setting = get_admin_settings_from_config(model_meta)
            for item in config_setting.get('list_filter'):
                if item not in list_filter:
                    list_filter.append(item)

            if config_setting.get('list_display'):
                list_display = config_setting.get('list_display')

        extra_context = {'title': 'Internal Search'}
        actions = self.get_actions(request)
        if actions:
            list_display = ['action_checkbox'] + list(list_display)

        kwargs = {
            'haystack_connection': self.haystack_connection,
            'request': request,
            'model': self.model,
            'list_display': list_display,
            'list_display_links': self.list_display_links,
            'list_filter': list_filter,
            'date_hierarchy': self.date_hierarchy,
            'search_fields': self.search_fields,
            'list_select_related': self.list_select_related,
            'list_per_page': self.list_per_page,
            'list_editable': self.list_editable,
            'model_admin': self,
            'list_max_show_all': self.list_max_show_all,
        }

        changelist = InternalSearchChangeList(**kwargs)
        changelist.formset = None
        media = self.media

        # If the request was POSTed, this might be a bulk action or a bulk
        # edit. Try to look up an action or confirmation first, but if this
        # isn't an action the POST will fall through to the bulk edit check,
        # below.
        action_failed = False
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)

        # Actions with no confirmation
        if (actions and request.method == 'POST' and 'index' in request.POST
                and '_save' not in request.POST):
            if selected:
                response = self.response_action(
                    request, queryset=changelist.get_queryset(request))
                if response:
                    return response
                else:
                    action_failed = True
            else:
                msg = _("Items must be selected in order to perform "
                        "actions on them. No items have been changed.")
                self.message_user(request, msg, messages.WARNING)
                action_failed = True

        # Actions with confirmation
        if (actions and request.method == 'POST'
                and helpers.ACTION_CHECKBOX_NAME in request.POST
                and 'index' not in request.POST
                and '_save' not in request.POST):
            if selected:
                response = self.response_action(
                    request, queryset=changelist.get_queryset(request))
                if response:
                    return response
                else:
                    action_failed = True

        if action_failed:
            # Redirect back to the changelist page to avoid resubmitting the
            # form if the user refreshes the browser or uses the "No, take
            # me back" button on the action confirmation page.
            return HttpResponseRedirect(request.get_full_path())

        # Build the action form and populate it with available actions.
        # Check actions to see if any are available on this changelist
        if actions:
            action_form = self.action_form(auto_id=None)
            action_form.fields['action'].choices = self.get_action_choices(
                request)
            media += action_form.media
        else:
            action_form = None

        selection_note = ungettext('0 of %(count)d selected',
                                   'of %(count)d selected',
                                   len(changelist.result_list))
        selection_note_all = ungettext('%(total_count)s selected',
                                       'All %(total_count)s selected',
                                       changelist.result_count)

        context = {
            'module_name':
            force_text(self.model._meta.verbose_name_plural),
            'selection_note':
            selection_note % {
                'count': len(changelist.result_list)
            },
            'selection_note_all':
            selection_note_all % {
                'total_count': changelist.result_count
            },
            'title':
            changelist.title,
            'is_popup':
            changelist.is_popup,
            'cl':
            changelist,
            'media':
            media,
            'has_add_permission':
            self.has_add_permission(request),
            'root_path':
            getattr(self.admin_site, 'root_path', None),
            'app_label':
            self.model._meta.app_label,
            'action_form':
            action_form,
            'actions_on_top':
            self.actions_on_top,
            'actions_on_bottom':
            self.actions_on_bottom,
            'actions_selection_counter':
            getattr(self, 'actions_selection_counter', 0),
            'opts':
            InternalSearchProxy._meta,
        }
        if extra_context:
            context.update(extra_context)

        request.current_app = self.admin_site.name
        app_name, model_name = get_model_ct_tuple(self.model)
        return render(
            request, self.change_list_template or [
                'admin/%s/%s/change_list.html' % (app_name, model_name),
                'admin/%s/change_list.html' % app_name,
                'admin/change_list.html'
            ], context)
Example #12
0
    def changelist_view(self, request, extra_context=None):
        if not self.has_change_permission(request, None):
            raise PermissionDenied

        list_filter = list(InternalSearchAdminSetting.list_filter)
        list_display = list(InternalSearchAdminSetting.list_display)

        model_meta = request.GET.get("type")
        if model_meta:
            config_setting = get_admin_settings_from_config(model_meta)
            for item in config_setting.get("list_filter"):
                if item not in list_filter:
                    list_filter.append(item)

            if config_setting.get("list_display"):
                list_display = config_setting.get("list_display")

        extra_context = {"title": "Internal Search"}
        actions = self.get_actions(request)
        if actions:
            list_display = ["action_checkbox"] + list(list_display)

        kwargs = {
            "haystack_connection": self.haystack_connection,
            "request": request,
            "model": self.model,
            "list_display": list_display,
            "list_display_links": self.list_display_links,
            "list_filter": list_filter,
            "date_hierarchy": self.date_hierarchy,
            "search_fields": self.search_fields,
            "list_select_related": self.list_select_related,
            "list_per_page": self.list_per_page,
            "list_editable": self.list_editable,
            "model_admin": self,
            "list_max_show_all": self.list_max_show_all,
        }

        changelist = InternalSearchChangeList(**kwargs)
        changelist.formset = None
        media = self.media

        # If the request was POSTed, this might be a bulk action or a bulk
        # edit. Try to look up an action or confirmation first, but if this
        # isn't an action the POST will fall through to the bulk edit check,
        # below.
        action_failed = False
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)

        # Actions with no confirmation
        if (
            actions
            and request.method == "POST"
            and "index" in request.POST
            and "_save" not in request.POST
        ):
            if selected:
                response = self.response_action(
                    request, queryset=changelist.get_queryset(request)
                )
                if response:
                    return response
                else:
                    action_failed = True
            else:
                msg = _(
                    "Items must be selected in order to perform "
                    "actions on them. No items have been changed."
                )
                self.message_user(request, msg, messages.WARNING)
                action_failed = True

        # Actions with confirmation
        if (
            actions
            and request.method == "POST"
            and helpers.ACTION_CHECKBOX_NAME in request.POST
            and "index" not in request.POST
            and "_save" not in request.POST
        ):
            if selected:
                response = self.response_action(
                    request, queryset=changelist.get_queryset(request)
                )
                if response:
                    return response
                else:
                    action_failed = True

        if action_failed:
            # Redirect back to the changelist page to avoid resubmitting the
            # form if the user refreshes the browser or uses the "No, take
            # me back" button on the action confirmation page.
            return HttpResponseRedirect(request.get_full_path())

        # Build the action form and populate it with available actions.
        # Check actions to see if any are available on this changelist
        if actions:
            action_form = self.action_form(auto_id=None)
            action_form.fields["action"].choices = self.get_action_choices(request)
            media += action_form.media
        else:
            action_form = None

        selection_note = ungettext(
            "0 of %(count)d selected",
            "of %(count)d selected",
            len(changelist.result_list),
        )
        selection_note_all = ungettext(
            "%(total_count)s selected",
            "All %(total_count)s selected",
            changelist.result_count,
        )

        context = {
            "module_name": force_text(self.model._meta.verbose_name_plural),
            "selection_note": selection_note % {"count": len(changelist.result_list)},
            "selection_note_all": selection_note_all
            % {"total_count": changelist.result_count},
            "title": changelist.title,
            "is_popup": changelist.is_popup,
            "cl": changelist,
            "media": media,
            "has_add_permission": self.has_add_permission(request),
            "root_path": getattr(self.admin_site, "root_path", None),
            "app_label": self.model._meta.app_label,
            "action_form": action_form,
            "actions_on_top": self.actions_on_top,
            "actions_on_bottom": self.actions_on_bottom,
            "actions_selection_counter": getattr(self, "actions_selection_counter", 0),
            "opts": InternalSearchProxy._meta,
        }
        if extra_context:
            context.update(extra_context)

        request.current_app = self.admin_site.name
        app_name, model_name = get_model_ct_tuple(self.model)
        return render(
            request,
            self.change_list_template
            or [
                "admin/%s/%s/change_list.html" % (app_name, model_name),
                "admin/%s/change_list.html" % app_name,
                "admin/change_list.html",
            ],
            context,
        )