Create a context manager that prevents updating of the search index

Given a model that has non-searchable fields that are updated often, this
context manager can prevent frivolous search index updates.
This commit is contained in:
Matt Molyneaux 2014-07-24 19:34:25 +01:00
parent 83d27e90bd
commit b3ff0947e8
3 changed files with 32 additions and 3 deletions

View file

@ -27,3 +27,4 @@ get_adapter = default_search_engine.get_adapter
# Easy context management.
update_index = search_context_manager.update_index
skip_index_update = search_context_manager.skip_index_update

View file

@ -232,7 +232,15 @@ class SearchContextManager(local):
The returned context manager can also be used as a decorator.
"""
return SearchContext(self)
def skip_index_update(self):
"""
Marks up a block of code as not requiring a search index update.
Like update_index, the returned context manager can also be used as a decorator.
"""
return SkipSearchContext(self)
# Signalling hooks.
def _request_finished_receiver(self, **kwargs):
@ -281,8 +289,21 @@ class SearchContext(object):
if not exception:
self.__exit__(None, None, None)
return do_search_context
class SkipSearchContext(SearchContext):
"""A context that skips over index updating"""
def __exit__(self, exc_type, exc_value, traceback):
"""Mark it as invalid and exit"""
try:
self._context_manager.invalidate()
finally:
self._context_manager.end()
# The shared, thread-safe search context manager.
search_context_manager = SearchContextManager()

View file

@ -244,6 +244,13 @@ class InternalsTest(SearchTestBase):
# Test a search that should get not model.
self.assertEqual(watson.search("fooo").count(), 0)
def testSkipSearchIndexUpdate(self):
with watson.skip_index_update():
self.test11.title = "fooo"
self.test11.save()
# Test a search that should get not model.
self.assertEqual(watson.search("fooo").count(), 0)
def testFixesDuplicateSearchEntries(self):
search_entries = SearchEntry.objects.filter(engine_slug="default")
# Duplicate a couple of search entries.