Removing hacky searchentry_set generic relation from registration and search process.

This commit is contained in:
Dave Hall 2012-02-06 13:21:58 +00:00
parent 9a81358159
commit eace6cf4d0
3 changed files with 49 additions and 16 deletions

View File

@ -59,11 +59,55 @@ class SearchBackend(object):
def do_filter(self, engine_slug, queryset, search_text):
"""Filters the given queryset according the the search logic for this backend."""
word_query = Q(searchentry_set__engine_slug=engine_slug)
model = queryset.model
db_table = connection.ops.quote_name(SearchEntry._meta.db_table)
model_db_table = connection.ops.quote_name(model._meta.db_table)
pk = model._meta.pk
id = connection.ops.quote_name(pk.db_column or pk.attname)
# Add in basic filters.
word_query = [u"""
({db_table}.{engine_slug} = %s)
""", """
({db_table}.{content_type_id} = %s)
"""]
word_kwargs= {
u"db_table": db_table,
u"model_db_table": model_db_table,
u"engine_slug": connection.ops.quote_name(u"engine_slug"),
u"title": connection.ops.quote_name(u"title"),
u"description": connection.ops.quote_name(u"description"),
u"content": connection.ops.quote_name(u"content"),
u"content_type_id": connection.ops.quote_name(u"content_type_id"),
u"object_id": connection.ops.quote_name(u"object_id"),
u"object_id_int": connection.ops.quote_name(u"object_id_int"),
u"id": id,
}
word_args = [
engine_slug,
ContentType.objects.get_for_model(model).id,
]
# Add in join.
if has_int_pk(model):
word_query.append("""
({db_table}.{object_id_int} = {model_db_table}.{id})
""")
else:
word_query.append("""
({db_table}.{object_id} = {model_db_table}.{id})
""")
# Add in all words.
for word in search_text.split():
regex = regex_from_word(word)
word_query &= (Q(searchentry_set__title__iregex=regex) | Q(searchentry_set__description__iregex=regex) | Q(searchentry_set__content__iregex=regex))
return queryset.filter(
word_query
word_query.append(u"""
({db_table}.{title} REGEXP '(?i)' || %s OR {db_table}.{description} REGEXP '(?i)' || %s OR {db_table}.{content} REGEXP '(?i)' || %s)
""")
word_args.extend((regex, regex, regex))
# Compile the query.
full_word_query = u" AND ".join(word_query).format(**word_kwargs)
return queryset.extra(
tables = (db_table,),
where = (full_word_query,),
params = word_args,
)
def do_filter_ranking(self, engine_slug, queryset, search_text):

View File

@ -345,18 +345,6 @@ class SearchEngine(object):
# Perform the registration.
adapter_obj = adapter_cls(model)
self._registered_models[model] = adapter_obj
# Add in a generic relation, if not exists.
if not hasattr(model, "searchentry_set"):
if has_int_pk(model):
object_id_field = "object_id_int"
else:
object_id_field = "object_id"
generic_relation = generic.GenericRelation(
SearchEntry,
object_id_field = object_id_field,
)
model.searchentry_set = generic_relation
generic_relation.contribute_to_class(model, "searchentry_set")
# Connect to the signalling framework.
post_save.connect(self._post_save_receiver, model)
pre_delete.connect(self._pre_delete_receiver, model)

View File

@ -197,7 +197,8 @@ class InternalsTest(SearchTestBase):
self.assertEqual(len(exact_search), 1)
self.assertEqual(exact_search[0].title, "fooo")
# Delete a model and make sure that the search results match.
self.test11.delete()
with watson.update_index():
self.test11.delete()
self.assertEqual(watson.search("fooo").count(), 0)
def testSearchIndexUpdateAbandonedOnError(self):