diff --git a/docs/howto/settings.rst b/docs/howto/settings.rst index f04c9d9c3..20b4b9472 100644 --- a/docs/howto/settings.rst +++ b/docs/howto/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' } } @@ -498,7 +498,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/docs/search/backends.rst b/docs/search/backends.rst index adf104484..8a6aaa49b 100644 --- a/docs/search/backends.rst +++ b/docs/search/backends.rst @@ -34,7 +34,7 @@ The backend is configured in settings: WAGTAILSEARCH_BACKENDS = { 'default': { - 'BACKEND': 'wagtail.wagtailsearch.backends.elasticsearch.ElasticSearch', + 'BACKEND': 'wagtail.wagtailsearch.backends.elasticsearch', 'URLS': ['http://localhost:9200'], 'INDEX': 'wagtail', 'TIMEOUT': 5, diff --git a/wagtail/tests/settings.py b/wagtail/tests/settings.py index c5e06592a..2c6d33932 100644 --- a/wagtail/tests/settings.py +++ b/wagtail/tests/settings.py @@ -135,7 +135,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', } } @@ -147,7 +147,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, } diff --git a/wagtail/wagtailsearch/backends/__init__.py b/wagtail/wagtailsearch/backends/__init__.py index fa6fcf017..0178b64ae 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 732de6195..2e789973e 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 ff9d8525c..77338c49a 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 ef22ae3c0..b576e9d6f 100644 --- a/wagtail/wagtailsearch/tests/test_backends.py +++ b/wagtail/wagtailsearch/tests/test_backends.py @@ -133,7 +133,7 @@ class BackendTests(WagtailTestUtils): @override_settings(WAGTAILSEARCH_BACKENDS={ - 'default': {'BACKEND': 'wagtail.wagtailsearch.backends.db.DBSearch'} + 'default': {'BACKEND': 'wagtail.wagtailsearch.backends.db'} }) class TestBackendLoader(TestCase): def test_import_by_name(self): @@ -141,11 +141,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 6af23f0e5..90cd118fb 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 7cccf6ba4..456dfc73a 100644 --- a/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py +++ b/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py @@ -13,7 +13,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