From f59c9fd573a932c347f9224c64890f703c270a87 Mon Sep 17 00:00:00 2001 From: Griatch Date: Thu, 13 Oct 2016 21:53:54 +0200 Subject: [PATCH] Fix bugs in alias-searching for objects. Resolves #1048. --- evennia/objects/manager.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/evennia/objects/manager.py b/evennia/objects/manager.py index d648c5003..82ba23d91 100644 --- a/evennia/objects/manager.py +++ b/evennia/objects/manager.py @@ -253,7 +253,7 @@ class ObjectDBManager(TypedObjectManager): # build query objects candidates_id = [_GA(obj, "id") for obj in make_iter(candidates) if obj] - cand_restriction = candidates != None and Q(pk__in=make_iter(candidates_id)) or Q() + cand_restriction = candidates != None and Q(pk__in=candidates_id) or Q() type_restriction = typeclasses and Q(db_typeclass_path__in=make_iter(typeclasses)) or Q() if exact: # exact match - do direct search @@ -261,23 +261,31 @@ class ObjectDBManager(TypedObjectManager): Q(db_tags__db_key__iexact=ostring) & Q(db_tags__db_tagtype__iexact="alias"))).distinct() elif candidates: # fuzzy with candidates - key_candidates = self.filter(cand_restriction & type_restriction) + search_candidates = self.filter(cand_restriction & type_restriction) else: # fuzzy without supplied candidates - we select our own candidates - key_candidates = self.filter(type_restriction & (Q(db_key__istartswith=ostring) | Q(db_tags__db_key__istartswith=ostring))).distinct() - candidates_id = [_GA(obj, "id") for obj in key_candidates] + search_candidates = self.filter(type_restriction & (Q(db_key__istartswith=ostring) | Q(db_tags__db_key__istartswith=ostring))).distinct() # fuzzy matching - key_strings = key_candidates.values_list("db_key", flat=True).order_by("id") + key_strings = search_candidates.values_list("db_key", flat=True).order_by("id") index_matches = string_partial_matching(key_strings, ostring, ret_index=True) if index_matches: - return [obj for ind, obj in enumerate(key_candidates) if ind in index_matches] + # a match by key + return [obj for ind, obj in enumerate(search_candidates) if ind in index_matches] else: - alias_candidates = self.filter(id__in=candidates_id, db_tags__db_tagtype__iexact="alias") - alias_strings = alias_candidates.values_list("db_key", flat=True) + # match by alias rather than by key + search_candidates = search_candidates.filter(db_tags__db_tagtype__iexact="alias", + db_tags__db_key__icontains=ostring) + alias_strings = [] + alias_candidates = [] + #TODO create the alias_strings and alias_candidates lists more effiently? + for candidate in search_candidates: + for alias in candidate.aliases.all(): + alias_strings.append(alias) + alias_candidates.append(candidate) index_matches = string_partial_matching(alias_strings, ostring, ret_index=True) if index_matches: - return [alias.db_obj for ind, alias in enumerate(alias_candidates) if ind in index_matches] + return [alias_candidates[ind] for ind in index_matches] return [] # main search methods and helper functions