diff --git a/tests/xapian_tests/tests/xapian_backend.py b/tests/xapian_tests/tests/xapian_backend.py index 024ffd8..fa9cf9c 100644 --- a/tests/xapian_tests/tests/xapian_backend.py +++ b/tests/xapian_tests/tests/xapian_backend.py @@ -15,10 +15,12 @@ from django.test import TestCase from haystack import indexes, sites, backends from haystack.backends.xapian_backend import SearchBackend, SearchQuery, _marshal_value from haystack.exceptions import HaystackError +from haystack.models import SearchResult from haystack.query import SearchQuerySet, SQ from haystack.sites import SearchSite from core.models import MockTag, MockModel, AnotherMockModel, AFourthMockModel +from core.tests.mocks import MockSearchResult class XapianMockModel(models.Model): @@ -188,6 +190,9 @@ class XapianSearchBackendTestCase(TestCase): self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [1, 2, 3]) self.assertEqual(self.backend.search(xapian.Query('indexed'))['hits'], 3) self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [1, 2, 3]) + + # Ensure that swapping the ``result_class`` works. + self.assertTrue(isinstance(self.backend.search(xapian.Query('indexed'), result_class=MockSearchResult)['results'][0], MockSearchResult)) def test_search_field_with_punctuation(self): self.backend.update(self.index, self.sample_objs) @@ -301,6 +306,9 @@ class XapianSearchBackendTestCase(TestCase): results = self.backend.more_like_this(self.sample_objs[0], limit_to_registered_models=True) self.assertEqual(results['hits'], 2) self.assertEqual([result.pk for result in results['results']], [3, 2]) + + # Ensure that swapping the ``result_class`` works. + self.assertTrue(isinstance(self.backend.more_like_this(self.sample_objs[0], result_class=MockSearchResult)['results'][0], MockSearchResult)) def test_order_by(self): self.backend.update(self.index, self.sample_objs) @@ -484,6 +492,38 @@ class LiveXapianSearchQueryTestCase(TestCase): settings.DEBUG = old_debug +class LiveXapianSearchQuerySetTestCase(TestCase): + """ + SearchQuerySet specific tests + """ + fixtures = ['initial_data.json'] + + def setUp(self): + super(LiveXapianSearchQuerySetTestCase, self).setUp() + + site = SearchSite() + backend = SearchBackend(site=site) + index = LiveXapianMockSearchIndex(MockModel, backend=backend) + site.register(MockModel, LiveXapianMockSearchIndex) + backend.update(index, MockModel.objects.all()) + + self.sq = SearchQuery(backend=backend) + self.sqs = SearchQuerySet(query=self.sq) + + def test_result_class(self): + # Assert that we're defaulting to ``SearchResult``. + sqs = self.sqs.all() + self.assertTrue(isinstance(sqs[0], SearchResult)) + + # Custom class. + sqs = self.sqs.result_class(MockSearchResult).all() + self.assertTrue(isinstance(sqs[0], MockSearchResult)) + + # Reset to default. + sqs = self.sqs.result_class(None).all() + self.assertTrue(isinstance(sqs[0], SearchResult)) + + class XapianBoostBackendTestCase(TestCase): def setUp(self): super(XapianBoostBackendTestCase, self).setUp() diff --git a/xapian_backend.py b/xapian_backend.py index 8fb3c88..44af56b 100755 --- a/xapian_backend.py +++ b/xapian_backend.py @@ -317,7 +317,7 @@ class SearchBackend(BaseSearchBackend): def search(self, query, sort_by=None, start_offset=0, end_offset=None, fields='', highlight=False, facets=None, date_facets=None, query_facets=None, narrow_queries=None, spelling_query=None, - limit_to_registered_models=True, **kwargs): + limit_to_registered_models=True, result_class=None, **kwargs): """ Executes the Xapian::query as defined in `query`. @@ -362,6 +362,9 @@ class SearchBackend(BaseSearchBackend): database = self._database() + if result_class is None: + result_class = SearchResult + if getattr(settings, 'HAYSTACK_INCLUDE_SPELLING', False) is True: spelling_suggestion = self._do_spelling_suggestion(database, query, spelling_query) else: @@ -424,7 +427,7 @@ class SearchBackend(BaseSearchBackend): ) } results.append( - SearchResult(app_label, module_name, pk, match.percent, **model_data) + result_class(app_label, module_name, pk, match.percent, **model_data) ) if facets: @@ -443,7 +446,7 @@ class SearchBackend(BaseSearchBackend): def more_like_this(self, model_instance, additional_query=None, start_offset=0, end_offset=None, - limit_to_registered_models=True, **kwargs): + limit_to_registered_models=True, result_class=None, **kwargs): """ Given a model instance, returns a result set of similar documents. @@ -475,6 +478,9 @@ class SearchBackend(BaseSearchBackend): """ database = self._database() + if result_class is None: + result_class = SearchResult + query = xapian.Query(DOCUMENT_ID_TERM_PREFIX + get_identifier(model_instance)) enquire = xapian.Enquire(database) @@ -521,7 +527,7 @@ class SearchBackend(BaseSearchBackend): for match in matches: app_label, module_name, pk, model_data = pickle.loads(self._get_document_data(database, match.document)) results.append( - SearchResult(app_label, module_name, pk, match.percent, **model_data) + result_class(app_label, module_name, pk, match.percent, **model_data) ) return {