diff --git a/docs/advanced_topics/settings.rst b/docs/advanced_topics/settings.rst index 94394c2eb9..c199c7a8ed 100644 --- a/docs/advanced_topics/settings.rst +++ b/docs/advanced_topics/settings.rst @@ -162,7 +162,7 @@ Search # Replace the search backend WAGTAILSEARCH_BACKENDS = { 'default': { - 'BACKEND': 'wagtail.wagtailsearch.backends.elasticsearch.ElasticSearch', + 'BACKEND': 'wagtail.wagtailsearch.backends.elasticsearch', 'INDEX': 'myapp' } } @@ -505,7 +505,7 @@ These two files should reside in your project directory (``myproject/myproject/` # Replace the search backend #WAGTAILSEARCH_BACKENDS = { # 'default': { - # 'BACKEND': 'wagtail.wagtailsearch.backends.elasticsearch.ElasticSearch', + # 'BACKEND': 'wagtail.wagtailsearch.backends.elasticsearch', # 'INDEX': 'myapp' # } #} diff --git a/wagtail/tests/settings.py b/wagtail/tests/settings.py index 580d3c4fa7..05edddeac4 100644 --- a/wagtail/tests/settings.py +++ b/wagtail/tests/settings.py @@ -132,7 +132,7 @@ COMPRESS_ENABLED = False # disable compression so that we can run tests on the WAGTAILSEARCH_BACKENDS = { 'default': { - 'BACKEND': 'wagtail.wagtailsearch.backends.db.DBSearch', + 'BACKEND': 'wagtail.wagtailsearch.backends.db', } } @@ -144,7 +144,7 @@ try: # Import succeeded, add an Elasticsearch backend WAGTAILSEARCH_BACKENDS['elasticsearch'] = { - 'BACKEND': 'wagtail.wagtailsearch.backends.elasticsearch.ElasticSearch', + 'BACKEND': 'wagtail.wagtailsearch.backends.elasticsearch', 'TIMEOUT': 10, 'max_retries': 1, 'AUTO_UPDATE': False, diff --git a/wagtail/wagtailsearch/backends/__init__.py b/wagtail/wagtailsearch/backends/__init__.py index 3877677ad8..c6e20ecaea 100644 --- a/wagtail/wagtailsearch/backends/__init__.py +++ b/wagtail/wagtailsearch/backends/__init__.py @@ -2,6 +2,9 @@ # Based on the Django cache framework # https://github.com/django/django/blob/5d263dee304fdaf95e18d2f0619d6925984a7f02/django/core/cache/__init__.py +import sys +import six +from importlib import import_module from django.utils.module_loading import import_string from django.core.exceptions import ImproperlyConfigured @@ -12,11 +15,34 @@ class InvalidSearchBackendError(ImproperlyConfigured): pass +def import_backend(dotted_path): + """ + Theres two formats for the dotted_path. + One with the backend class (old) and one without (new) + eg: + old: wagtail.wagtailsearch.backends.elasticsearch.ElasticSearch + new: wagtail.wagtailsearch.backends.elasticsearch + + If a new style dotted path was specified, this function would + look for a backend class from the "SearchBackend" attribute. + """ + try: + # New + backend_module = import_module(dotted_path) + return backend_module.SearchBackend + except ImportError as e: + try: + # Old + return import_string(dotted_path) + except ImportError: + six.reraise(ImportError, e, sys.exc_info()[2]) + + def get_search_backend(backend='default', **kwargs): # Get configuration default_conf = { 'default': { - 'BACKEND': 'wagtail.wagtailsearch.backends.db.DBSearch', + 'BACKEND': 'wagtail.wagtailsearch.backends.db', }, } WAGTAILSEARCH_BACKENDS = getattr( @@ -29,7 +55,7 @@ def get_search_backend(backend='default', **kwargs): except KeyError: try: # Trying to import the given backend, in case it's a dotted path - import_string(backend) + import_backend(backend) except ImportError as e: raise InvalidSearchBackendError("Could not find backend '%s': %s" % ( backend, e)) @@ -42,7 +68,7 @@ def get_search_backend(backend='default', **kwargs): # Try to import the backend try: - backend_cls = import_string(backend) + backend_cls = import_backend(backend) except ImportError as e: raise InvalidSearchBackendError("Could not find backend '%s': %s" % ( backend, e)) diff --git a/wagtail/wagtailsearch/backends/db.py b/wagtail/wagtailsearch/backends/db.py index 732de6195d..2e789973ef 100644 --- a/wagtail/wagtailsearch/backends/db.py +++ b/wagtail/wagtailsearch/backends/db.py @@ -93,3 +93,6 @@ class DBSearch(BaseSearch): def _search(self, queryset, query_string, fields=None): return DBSearchResults(self, DBSearchQuery(queryset, query_string, fields=fields)) + + +SearchBackend = DBSearch diff --git a/wagtail/wagtailsearch/backends/elasticsearch.py b/wagtail/wagtailsearch/backends/elasticsearch.py index ff9d8525ce..77338c49a4 100644 --- a/wagtail/wagtailsearch/backends/elasticsearch.py +++ b/wagtail/wagtailsearch/backends/elasticsearch.py @@ -465,3 +465,6 @@ class ElasticSearch(BaseSearch): def _search(self, queryset, query_string, fields=None): return ElasticSearchResults(self, ElasticSearchQuery(queryset, query_string, fields=fields)) + + +SearchBackend = ElasticSearch diff --git a/wagtail/wagtailsearch/tests/test_backends.py b/wagtail/wagtailsearch/tests/test_backends.py index 9a50d9c42a..11df7ee6cb 100644 --- a/wagtail/wagtailsearch/tests/test_backends.py +++ b/wagtail/wagtailsearch/tests/test_backends.py @@ -134,7 +134,7 @@ class BackendTests(WagtailTestUtils): @override_settings( WAGTAILSEARCH_BACKENDS={ - 'default': {'BACKEND': 'wagtail.wagtailsearch.backends.db.DBSearch'} + 'default': {'BACKEND': 'wagtail.wagtailsearch.backends.db'} } ) class TestBackendLoader(TestCase): @@ -143,11 +143,15 @@ class TestBackendLoader(TestCase): self.assertIsInstance(db, DBSearch) def test_import_by_path(self): + db = get_search_backend(backend='wagtail.wagtailsearch.backends.db') + self.assertIsInstance(db, DBSearch) + + def test_import_by_full_path(self): db = get_search_backend(backend='wagtail.wagtailsearch.backends.db.DBSearch') self.assertIsInstance(db, DBSearch) def test_nonexistent_backend_import(self): - self.assertRaises(InvalidSearchBackendError, get_search_backend, backend='wagtail.wagtailsearch.backends.doesntexist.DoesntExist') + self.assertRaises(InvalidSearchBackendError, get_search_backend, backend='wagtail.wagtailsearch.backends.doesntexist') def test_invalid_backend_import(self): self.assertRaises(InvalidSearchBackendError, get_search_backend, backend="I'm not a backend!") diff --git a/wagtail/wagtailsearch/tests/test_db_backend.py b/wagtail/wagtailsearch/tests/test_db_backend.py index 6af23f0e5e..90cd118fb7 100644 --- a/wagtail/wagtailsearch/tests/test_db_backend.py +++ b/wagtail/wagtailsearch/tests/test_db_backend.py @@ -6,7 +6,7 @@ from .test_backends import BackendTests class TestDBBackend(BackendTests, TestCase): - backend_path = 'wagtail.wagtailsearch.backends.db.DBSearch' + backend_path = 'wagtail.wagtailsearch.backends.db' @unittest.expectedFailure def test_callable_indexed_field(self): diff --git a/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py b/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py index 4ce929e38e..b0d81f7c1f 100644 --- a/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py +++ b/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py @@ -15,7 +15,7 @@ from .test_backends import BackendTests class TestElasticSearchBackend(BackendTests, TestCase): - backend_path = 'wagtail.wagtailsearch.backends.elasticsearch.ElasticSearch' + backend_path = 'wagtail.wagtailsearch.backends.elasticsearch' def test_search_with_spaces_only(self): # Search for some space characters and hope it doesn't crash