コード例 #1
0
ファイル: tests.py プロジェクト: exoanalytic/django-haystack
    def test_searchqueryset_using(self):
        # Using the default.
        sqs = SearchQuerySet()
        self.assertEqual(sqs.count(), 5)
        self.assertEqual(sqs.models(Foo).count(), 2)
        self.assertEqual(sqs.models(Bar).count(), 3)

        self.assertEqual(sqs.using("default").count(), 5)
        self.assertEqual(sqs.using("default").models(Foo).count(), 2)
        self.assertEqual(sqs.using("default").models(Bar).count(), 3)

        self.assertEqual(sqs.using("whoosh").count(), 2)
        self.assertEqual(sqs.using("whoosh").models(Foo).count(), 2)
        self.assertEqual(sqs.using("whoosh").models(Bar).count(), 0)
コード例 #2
0
    def test_searchqueryset_using(self):
        # Using the default.
        sqs = SearchQuerySet('solr')
        self.assertEqual(sqs.count(), 5)
        self.assertEqual(sqs.models(Foo).count(), 2)
        self.assertEqual(sqs.models(Bar).count(), 3)

        self.assertEqual(sqs.using('solr').count(), 5)
        self.assertEqual(sqs.using('solr').models(Foo).count(), 2)
        self.assertEqual(sqs.using('solr').models(Bar).count(), 3)

        self.assertEqual(sqs.using('whoosh').count(), 2)
        self.assertEqual(sqs.using('whoosh').models(Foo).count(), 2)
        self.assertEqual(sqs.using('whoosh').models(Bar).count(), 0)
コード例 #3
0
ファイル: manager.py プロジェクト: becca51178/govtrack.us-web
    def queryset(self, postdata, exclude=None):
        """
        Build the `self.model` queryset limited to selected filters.
        """
        
        if not self.qs:
            #qs = self.model.objects.all().select_related()
            from haystack.query import SearchQuerySet
            qs = SearchQuerySet()
            if self.connection: qs = qs.using(self.connection)
            qs = qs.filter(indexed_model_name__in=[self.model.__name__], **self.global_filters)
        else:
            qs = self.qs

        filters = { }
        
        # Then for each filter
        for option in self.options:
            # If filter is not excluded explicitly (used to get counts
            # for choices).
            if option == exclude: continue
            
            # If filter contains valid data, check jQuery style encoding of array params
            if option.field_name not in postdata and option.field_name+"[]" not in postdata: continue
            
            # Do filtering

            if option.filter is not None:
                qs_ = option.filter(qs, postdata)
                
                if isinstance(qs_, dict):
                    filters.update(qs_)
                else:
                    qs = qs_
                
            else:
                def clean_values(x):
                    for y in x:
                        if y in ("true", "on"):
                            yield True
                        elif y == "false":
                            yield False
                        else:                        
                            yield y
                values = list(clean_values(postdata.getlist(option.field_name)+postdata.getlist(option.field_name+"[]")))
                if option.type == "text":
                    # For full-text searching, don't use __in so that the search
                    # backend does its usual query operation.
                    filters[option.field_name] = " ".join(values)
                elif not u'__ALL__' in values:
                    # if __ALL__ value presents in filter values
                    # then do not limit queryset
                    filters['%s__in' % option.field_name] = values

        # apply filters simultaneously so that filters on related objects are applied
        # to the same related object. if they were applied chained (i.e. filter().filter())
        # then they could apply to different objects.
        if len(filters) > 0:
            qs = qs.filter(**filters)
            
        for name, key, default in self.sort_options:
            if postdata.get("sort", "") == key:
                qs = qs.order_by(key)
        
        # Django ORM but not Haystack
        if hasattr(qs, 'distinct'):
            return qs.distinct()
            
        # Haystack but not Django ORM
        else:
            # Revise the SearchQuerySet to iterate over model objects
            # rather than SearchResult objects.
            class SR:
                def __init__(self, qs):
                    self.qs = qs
                def facet(self, field, **kwargs):
                    return self.qs.facet(field, **kwargs)
                def count(self):
                    return len(self.qs)
                def order_by(self, field):
                    return SR(self.qs.order_by(field))
                def __len__(self):
                    return len(self.qs)
                def __getitem__(self, index): # slices too
                    return SR(self.qs[index])
                def __iter__(self):
                    for item in self.qs:
                        yield item.object
            return SR(qs)
コード例 #4
0
    def queryset(self, postdata, exclude=None):
        """
        Build the `self.model` queryset limited to selected filters.
        """

        from haystack.query import SearchQuerySet

        if self.qs is None:
            #qs = self.model.objects.all().select_related()
            qs = SearchQuerySet()
            if self.connection: qs = qs.using(self.connection)
            qs = qs.filter(indexed_model_name__in=[self.model.__name__],
                           **self.global_filters)
        else:
            qs = self.qs

        filters = {}
        filters2 = []

        # Then for each filter
        for option in self.options:
            # If filter is not excluded explicitly (used to get counts
            # for choices).
            if option == exclude: continue

            # If filter contains valid data, check jQuery style encoding of array params
            if option.field_name not in postdata and option.field_name + "[]" not in postdata:
                continue

            # Do filtering

            if option.filter is not None:
                qs_ = option.filter(qs, postdata)

                if isinstance(qs_, dict):
                    filters.update(qs_)
                else:
                    qs = qs_

            else:
                values = postdata.getlist(
                    option.field_name) + postdata.getlist(option.field_name +
                                                          "[]")

                if option.type == "text":
                    # For full-text searching, don't use __in so that the search
                    # backend does its usual query operation.
                    values = " ".join(
                        values
                    )  # should not really be more than one, but in case the parameter is specified multiple times in the query string
                    if self.qs is None:
                        # This is a Haystack search. Handle text a little differently.
                        # Wrap it in an AutoQuery so advanced search options like quoted phrases are used.
                        # Query both text and text_boosted, which has a boost applied at the field level.
                        from haystack.query import SQ
                        from haystack.inputs import AutoQuery
                        values = AutoQuery(values)
                        filters2.append(
                            SQ(text=values) | SQ(text_boosted=values))
                    else:
                        filters[option.orm_field_name] = values

                elif not '__ALL__' in values:
                    # if __ALL__ value presents in filter values
                    # then do not limit queryset

                    def parse_booleans(x):
                        for y in x:
                            if y in ("true", "on"):
                                yield True
                            elif y == "false":
                                yield False
                            else:
                                yield y

                    values = list(parse_booleans(values))

                    filters['%s__in' % option.orm_field_name] = values

        # apply filters simultaneously so that filters on related objects are applied
        # to the same related object. if they were applied chained (i.e. filter().filter())
        # then they could apply to different objects.
        if len(filters) + len(filters2) > 0:
            qs = qs.filter(*filters2, **filters)

        for name, key, default, func in self.sort_options:
            if postdata.get("sort", "") == key:
                if not func:
                    qs = qs.order_by(key)
                else:
                    qs = func(qs)

        # Django ORM but not Haystack
        if hasattr(qs, 'distinct'):
            return qs.distinct()

        # Haystack but not Django ORM
        elif isinstance(qs, SearchQuerySet):
            # Revise the SearchQuerySet to iterate over model objects
            # rather than SearchResult objects.
            class SR:
                def __init__(self, qs, manager):
                    self.qs = qs
                    self.manager = manager

                def facet(self, field, **kwargs):
                    return self.qs.facet(field, **kwargs)

                def count(self):
                    return len(self.qs)

                def order_by(self, field):
                    return SR(self.qs.order_by(field), self.manager)

                def __len__(self):
                    return len(self.qs)

                def __getitem__(self, index):  # slices too, yields a list?
                    return SR(self.qs[index], self.manager)

                def __iter__(self):
                    # Pre-load all objects in bulk. Then yield in the right order.
                    objects = self.manager.bulk_loader(item.pk
                                                       for item in self.qs)
                    for item in self.qs:
                        yield objects[int(item.pk)]

            return SR(qs, self)

        else:
            raise ValueError(qs)
コード例 #5
0
ファイル: tests.py プロジェクト: exoanalytic/django-haystack
    def test_handle_delete(self):
        # Because the code here is pretty leaky (abstraction-wise), we'll test
        # the actual setup.
        # First, ensure the signal is setup.
        self.assertEqual(len(models.signals.post_delete.receivers), 1)

        # Second, check the existing search data.
        sqs = SearchQuerySet()
        self.assertEqual(sqs.using("default").count(), 5)
        self.assertEqual(sqs.using("default").models(Foo).count(), 2)
        self.assertEqual(sqs.using("default").models(Bar).count(), 3)
        self.assertEqual(sqs.using("whoosh").count(), 2)
        self.assertEqual(sqs.using("whoosh").models(Foo).count(), 2)

        self.assertEqual(sqs.using("default").models(Foo).order_by("django_id")[0].text, "foo 1")
        self.assertEqual(sqs.using("whoosh").models(Foo).order_by("django_id")[0].text, "foo 1")

        # Third, delete the model, which should fire the signal & remove the
        # record from the index.
        self.foo_1.delete()

        # Fourth, check the search data for the now-removed data, making sure counts
        # have changed correctly.
        sqs = SearchQuerySet()
        self.assertEqual(sqs.using("default").count(), 4)
        self.assertEqual(sqs.using("default").models(Foo).count(), 1)
        self.assertEqual(sqs.using("default").models(Bar).count(), 3)
        self.assertEqual(sqs.using("whoosh").count(), 2)
        self.assertEqual(sqs.using("whoosh").models(Foo).count(), 2)

        self.assertEqual(sqs.using("default").models(Foo).order_by("django_id")[0].text, "foo 2")
        self.assertEqual(sqs.using("whoosh").models(Foo).order_by("django_id")[0].text, "foo 1")
コード例 #6
0
ファイル: tests.py プロジェクト: exoanalytic/django-haystack
    def test_handle_save(self):
        # Because the code here is pretty leaky (abstraction-wise), we'll test
        # the actual setup.
        # First, ensure the signal is setup.
        self.assertEqual(len(models.signals.post_save.receivers), 1)

        # Second, check the existing search data.
        sqs = SearchQuerySet()
        self.assertEqual(sqs.using("default").count(), 5)
        self.assertEqual(sqs.using("default").models(Foo).count(), 2)
        self.assertEqual(sqs.using("default").models(Bar).count(), 3)
        self.assertEqual(sqs.using("whoosh").count(), 2)
        self.assertEqual(sqs.using("whoosh").models(Foo).count(), 2)

        self.assertEqual(sqs.using("default").models(Foo).order_by("django_id")[0].text, "foo 1")
        self.assertEqual(sqs.using("whoosh").models(Foo).order_by("django_id")[0].text, "foo 1")

        # Third, save the model, which should fire the signal & index the
        # new data.
        self.foo_1.body = "A different body"
        self.foo_1.save()

        # Fourth, check the search data for the updated data, making sure counts
        # haven't changed.
        sqs = SearchQuerySet()
        self.assertEqual(sqs.using("default").count(), 5)
        self.assertEqual(sqs.using("default").models(Foo).count(), 2)
        self.assertEqual(sqs.using("default").models(Bar).count(), 3)
        self.assertEqual(sqs.using("whoosh").count(), 2)
        self.assertEqual(sqs.using("whoosh").models(Foo).count(), 2)

        self.assertEqual(sqs.using("default").models(Foo).order_by("django_id")[0].text, "A different body")
        self.assertEqual(sqs.using("whoosh").models(Foo).order_by("django_id")[0].text, "foo 1")
コード例 #7
0
    def test_handle_delete(self):
        # Because the code here is pretty leaky (abstraction-wise), we'll test
        # the actual setup.
        # First, ensure the signal is setup.
        self.assertEqual(len(models.signals.post_delete.receivers), 1)

        # Second, check the existing search data.
        sqs = SearchQuerySet('solr')
        self.assertEqual(sqs.using('solr').count(), 5)
        self.assertEqual(sqs.using('solr').models(Foo).count(), 2)
        self.assertEqual(sqs.using('solr').models(Bar).count(), 3)
        self.assertEqual(sqs.using('whoosh').count(), 2)
        self.assertEqual(sqs.using('whoosh').models(Foo).count(), 2)

        self.assertEqual(
            sqs.using('solr').models(Foo).order_by('django_id')[0].text,
            'foo 1')
        self.assertEqual(
            sqs.using('whoosh').models(Foo).order_by('django_id')[0].text,
            'foo 1')

        # Third, delete the model, which should fire the signal & remove the
        # record from the index.
        self.foo_1.delete()

        # Fourth, check the search data for the now-removed data, making sure counts
        # have changed correctly.
        sqs = SearchQuerySet('solr')
        self.assertEqual(sqs.using('solr').count(), 4)
        self.assertEqual(sqs.using('solr').models(Foo).count(), 1)
        self.assertEqual(sqs.using('solr').models(Bar).count(), 3)
        self.assertEqual(sqs.using('whoosh').count(), 2)
        self.assertEqual(sqs.using('whoosh').models(Foo).count(), 2)

        self.assertEqual(
            sqs.using('solr').models(Foo).order_by('django_id')[0].text,
            'foo 2')
        self.assertEqual(
            sqs.using('whoosh').models(Foo).order_by('django_id')[0].text,
            'foo 1')
コード例 #8
0
    def test_handle_save(self):
        # Because the code here is pretty leaky (abstraction-wise), we'll test
        # the actual setup.
        # First, ensure the signal is setup.
        self.assertEqual(len(models.signals.post_save.receivers), 1)

        # Second, check the existing search data.
        sqs = SearchQuerySet('solr')
        self.assertEqual(sqs.using('solr').count(), 5)
        self.assertEqual(sqs.using('solr').models(Foo).count(), 2)
        self.assertEqual(sqs.using('solr').models(Bar).count(), 3)
        self.assertEqual(sqs.using('whoosh').count(), 2)
        self.assertEqual(sqs.using('whoosh').models(Foo).count(), 2)

        self.assertEqual(
            sqs.using('solr').models(Foo).order_by('django_id')[0].text,
            'foo 1')
        self.assertEqual(
            sqs.using('whoosh').models(Foo).order_by('django_id')[0].text,
            'foo 1')

        # Third, save the model, which should fire the signal & index the
        # new data.
        self.foo_1.body = 'A different body'
        self.foo_1.save()

        # Fourth, check the search data for the updated data, making sure counts
        # haven't changed.
        sqs = SearchQuerySet('solr')
        self.assertEqual(sqs.using('solr').count(), 5)
        self.assertEqual(sqs.using('solr').models(Foo).count(), 2)
        self.assertEqual(sqs.using('solr').models(Bar).count(), 3)
        self.assertEqual(sqs.using('whoosh').count(), 2)
        self.assertEqual(sqs.using('whoosh').models(Foo).count(), 2)

        self.assertEqual(
            sqs.using('solr').models(Foo).order_by('django_id')[0].text,
            'A different body')
        self.assertEqual(
            sqs.using('whoosh').models(Foo).order_by('django_id')[0].text,
            'foo 1')
コード例 #9
0
ファイル: manager.py プロジェクト: Saworieza/govtrack.us-web
    def queryset(self, postdata, exclude=None):
        """
        Build the `self.model` queryset limited to selected filters.
        """
        
        if self.qs is None:
            #qs = self.model.objects.all().select_related()
            from haystack.query import SearchQuerySet
            qs = SearchQuerySet()
            if self.connection: qs = qs.using(self.connection)
            qs = qs.filter(indexed_model_name__in=[self.model.__name__], **self.global_filters)
        else:
            qs = self.qs

        filters = { }
        filters2 = []
        
        # Then for each filter
        for option in self.options:
            # If filter is not excluded explicitly (used to get counts
            # for choices).
            if option == exclude: continue
            
            # If filter contains valid data, check jQuery style encoding of array params
            if option.field_name not in postdata and option.field_name+"[]" not in postdata: continue
            
            # Do filtering

            if option.filter is not None:
                qs_ = option.filter(qs, postdata)
                
                if isinstance(qs_, dict):
                    filters.update(qs_)
                else:
                    qs = qs_
                
            else:
                values = postdata.getlist(option.field_name)+postdata.getlist(option.field_name+"[]")
                
                if option.type == "text":
                    # For full-text searching, don't use __in so that the search
                    # backend does its usual query operation.
                    values = " ".join(values) # should not really be more than one, but in case the parameter is specified multiple times in the query string
                    if self.qs is None:
                       # This is a Haystack search. Handle text a little differently.
                       # Wrap it in an AutoQuery so advanced search options like quoted phrases are used.
                       # Query both text and text_boosted, which has a boost applied at the field level.
                       from haystack.query import SQ
                       from haystack.inputs import AutoQuery
                       values = AutoQuery(values)
                       filters2.append( SQ(text=values) | SQ(text_boosted=values) )
                    else:
                       filters[option.orm_field_name] = values
                    
                elif not u'__ALL__' in values:
                    # if __ALL__ value presents in filter values
                    # then do not limit queryset

                    def parse_booleans(x):
                        for y in x:
                            if y in ("true", "on"):
                                yield True
                            elif y == "false":
                                yield False
                            else:                        
                                yield y
                    values = list(parse_booleans(values))

                    filters['%s__in' % option.orm_field_name] = values

        # apply filters simultaneously so that filters on related objects are applied
        # to the same related object. if they were applied chained (i.e. filter().filter())
        # then they could apply to different objects.
        if len(filters) + len(filters2) > 0:
            qs = qs.filter(*filters2, **filters)
            
        for name, key, default, func in self.sort_options:
            if postdata.get("sort", "") == key:
                if not func:
                    qs = qs.order_by(key)
                else:
                    qs = func(qs)
        
        # Django ORM but not Haystack
        if hasattr(qs, 'distinct'):
            return qs.distinct()
            
        # Haystack but not Django ORM
        else:
            # Revise the SearchQuerySet to iterate over model objects
            # rather than SearchResult objects.
            class SR:
                def __init__(self, qs):
                    self.qs = qs
                def facet(self, field, **kwargs):
                    return self.qs.facet(field, **kwargs)
                def count(self):
                    return len(self.qs)
                def order_by(self, field):
                    return SR(self.qs.order_by(field))
                def __len__(self):
                    return len(self.qs)
                def __getitem__(self, index): # slices too
                    return SR(self.qs[index])
                def __iter__(self):
                    for item in self.qs:
                        yield item.object
            return SR(qs)