Example #1
0
    def build_query(self, **filters):
        """
        Creates a dict of dictionaries suitable for passing to the  SearchQuerySet `facet`,
        `date_facet` or `query_facet` method. All key word arguments should be wrapped in a list.

        :param view: API View
        :param dict[str, list[str]] filters: is an expanded QueryDict or a mapping
        of keys to a list of parameters.
        """
        field_facets = {}
        date_facets = {}
        query_facets = {}
        facet_serializer_cls = self.view.get_facet_serializer_class()

        if self.view.lookup_sep == ":":
            raise AttributeError("The %(cls)s.lookup_sep attribute conflicts with the HaystackFacetFilter "
                                 "query parameter parser. Please choose another `lookup_sep` attribute "
                                 "for %(cls)s." % {"cls": self.view.__class__.__name__})

        fields = facet_serializer_cls.Meta.fields
        exclude = facet_serializer_cls.Meta.exclude
        field_options = facet_serializer_cls.Meta.field_options

        for field, options in filters.items():

            if field not in fields or field in exclude:
                continue

            field_options = merge_dict(field_options, {field: self.parse_field_options(self.view.lookup_sep, *options)})

        valid_gap = ("year", "month", "day", "hour", "minute", "second")
        for field, options in field_options.items():
            if any([k in options for k in ("start_date", "end_date", "gap_by", "gap_amount")]):

                if not all(("start_date", "end_date", "gap_by" in options)):
                    raise ValueError("Date faceting requires at least 'start_date', 'end_date' "
                                     "and 'gap_by' to be set.")

                if not options["gap_by"] in valid_gap:
                    raise ValueError("The 'gap_by' parameter must be one of %s." % ", ".join(valid_gap))

                options.setdefault("gap_amount", 1)
                date_facets[field] = field_options[field]

            else:
                field_facets[field] = field_options[field]

        return {
            "date_facets": date_facets,
            "field_facets": field_facets,
            "query_facets": query_facets
        }
Example #2
0
 def test_utils_merge_dict(self):
     self.assertEqual(merge_dict(self.dict_a, self.dict_b), {
         "person": {
             "gender": "male",
             "firstname": "Sherlock",
             "lastname": "Holmes",
             "location": {
                 "address": "221B Baker Street"
             },
             "combat_proficiency": [
                 "Martial arts",
                 "Pistol",
                 "boxing",
                 "sword",
             ]
         }
     })
Example #3
0
 def test_utils_merge_dict(self):
     self.assertEqual(
         merge_dict(self.dict_a, self.dict_b),
         {
             "person": {
                 "gender": "male",
                 "firstname": "Sherlock",
                 "lastname": "Holmes",
                 "location": {"address": "221B Baker Street"},
                 "combat_proficiency": [
                     "Martial arts",
                     "Pistol",
                     "boxing",
                     "sword",
                 ],
             }
         },
     )
    def build_query(self, **filters):
        """
        Creates a dict of dictionaries suitable for passing to the
        SearchQuerySet `facet`,
        `date_facet` or `query_facet` method. All key word arguments
        should be wrapped in a list.

        :param view: API View
        :param dict[str, list[str]] filters: is an expanded QueryDict or
         a mapping
        of keys to a list of parameters.
        """
        field_facets = {}
        date_facets = {}
        query_facets = {}
        range_facets = {}
        heatmap_facets = {}
        facets_options = {}
        facet_serializer_cls = self.view.get_facet_serializer_class()

        if self.view.lookup_sep == ":":
            raise AttributeError(
                "The %(cls)s.lookup_sep attribute conflicts with the "
                "HaystackFacetFilter query parameter parser. Please choose "
                "another `lookup_sep` attribute for %(cls)s." %
                {"cls": self.view.__class__.__name__})

        fields = facet_serializer_cls.Meta.fields
        exclude = facet_serializer_cls.Meta.exclude
        field_options = facet_serializer_cls.Meta.field_options

        for field, options in filters.items():
            if not field.startswith("facet.field."):
                continue

            field = field[len("facet.field."):]

            if field not in fields or field in exclude:
                continue

            field_options = merge_dict(
                field_options, {field: self.parse_field_options(*options)})

        for field, options in filters.items():
            if not field.startswith("facet.heatmap."):
                continue

            field = field[len("facet.heatmap."):]

            if field not in fields or field in exclude:
                continue

            heatmap_options = self.parse_field_options(*options)
            heatmap_facets[field] = heatmap_options

        valid_gap = ("year", "month", "day", "hour", "minute", "second")
        for field, options in field_options.items():
            if any([
                    k in options
                    for k in ("start_date", "end_date", "gap_by", "gap_amount")
            ]):

                if not all(("start_date", "end_date", "gap_by" in options)):
                    raise ValueError(
                        "Date faceting requires at least 'start_date', "
                        "'end_date' and 'gap_by' to be set.")

                if not options["gap_by"] in valid_gap:
                    raise ValueError(
                        "The 'gap_by' parameter must be one of %s." %
                        ", ".join(valid_gap))

                options.setdefault("gap_amount", 1)
                date_facets[field] = field_options[field]
            elif any([k in options for k in ("start", "end", "gap")]):

                if not all(("start", "end", "gap" in options)):
                    raise ValueError(
                        "Range faceting requires at least 'start', 'end' "
                        "and 'gap' to be set.")

                range_facets[field] = field_options[field]
            else:
                field_facets[field] = field_options[field]

        for field, options in filters.items():
            if field in ("facet.mincount", "facet.missing"):
                facets_options[field] = options

        return {
            "date_facets": date_facets,
            "field_facets": field_facets,
            "query_facets": query_facets,
            "range_facets": range_facets,
            "facets_options": facets_options,
            "heatmap_facets": heatmap_facets,
        }
Example #5
0
 def test_utils_merge_dict_invalid_input(self):
     self.assertEqual(merge_dict(self.dict_a, "I'm not a dict!"),
                      "I'm not a dict!")
Example #6
0
 def test_utils_merge_dict_invalid_input(self):
     self.assertEqual(merge_dict(self.dict_a, "I'm not a dict!"), "I'm not a dict!")