Rewrote the fuzzy-matching routine to correctly handle fuzzy, global searches on keys and aliases.
This commit is contained in:
commit
87bfb97853
1 changed files with 31 additions and 29 deletions
|
|
@ -186,32 +186,27 @@ class ObjectManager(TypedObjectManager):
|
||||||
candidates_id = [_GA(obj, "id") for obj in make_iter(candidates) if obj]
|
candidates_id = [_GA(obj, "id") for obj in make_iter(candidates) if obj]
|
||||||
cand_restriction = candidates and Q(pk__in=candidates_id) or Q()
|
cand_restriction = candidates and Q(pk__in=candidates_id) or Q()
|
||||||
if exact:
|
if exact:
|
||||||
|
# exact match - do direct search
|
||||||
return self.filter(cand_restriction & (Q(db_key__iexact=ostring) | Q(alias__db_key__iexact=ostring))).distinct()
|
return self.filter(cand_restriction & (Q(db_key__iexact=ostring) | Q(alias__db_key__iexact=ostring))).distinct()
|
||||||
|
elif candidates:
|
||||||
|
# fuzzy with candidates
|
||||||
|
key_candidates = self.filter(cand_restriction)
|
||||||
else:
|
else:
|
||||||
if candidates:
|
# fuzzy without supplied candidates - we select our own candidates
|
||||||
# fuzzy matching - only check the candidates
|
key_candidates = self.filter(Q(db_key__istartswith=ostring) | Q(alias__db_key__istartswith=ostring)).distinct()
|
||||||
key_candidates = self.filter(cand_restriction)
|
candidates_id = [_GA(obj, "id") for obj in key_candidates]
|
||||||
key_strings = key_candidates.values_list("db_key", flat=True)
|
# fuzzy matching
|
||||||
index_matches = string_partial_matching(key_strings, ostring, ret_index=True)
|
key_strings = key_candidates.values_list("db_key", flat=True)
|
||||||
if index_matches:
|
index_matches = string_partial_matching(key_strings, ostring, ret_index=True)
|
||||||
return [obj for ind, obj in enumerate(key_candidates) if ind in index_matches]
|
if index_matches:
|
||||||
else:
|
return [obj for ind, obj in enumerate(key_candidates) if ind in index_matches]
|
||||||
alias_candidates = self.model.alias_set.related.model.objects.filter(db_obj__pk__in=candidates_id)
|
else:
|
||||||
alias_strings = alias_candidates.values_list("db_key", flat=True)
|
alias_candidates = self.model.alias_set.related.model.objects.filter(db_obj__pk__in=candidates_id)
|
||||||
index_matches = string_partial_matching(alias_strings, ostring, ret_index=True)
|
alias_strings = alias_candidates.values_list("db_key", flat=True)
|
||||||
if index_matches:
|
index_matches = string_partial_matching(alias_strings, ostring, ret_index=True)
|
||||||
return [alias.db_obj for ind, alias in enumerate(alias_candidates) if ind in index_matches]
|
if index_matches:
|
||||||
return []
|
return [alias.db_obj for ind, alias in enumerate(alias_candidates) if ind in index_matches]
|
||||||
else:
|
return []
|
||||||
# fuzzy matching - first check with keys, then with aliases
|
|
||||||
key_candidates = self.filter(Q(db_key__istartswith=ostring) | Q(alias__db_key__istartswith=ostring)).distinct()
|
|
||||||
key_strings = key_candidates.values_list("db_key", flat=True)
|
|
||||||
matches = string_partial_matching(key_candidates, ostring, reg_index=False)
|
|
||||||
if matches:
|
|
||||||
return matches
|
|
||||||
alias_candidates = self.model.alias_set.related.model.objects.filter(db_obj__pk__in=candidates_id).values_list("db_key", flat=True)
|
|
||||||
return string_partial_matching(alias_candidates, ostring, ret_index=False)
|
|
||||||
|
|
||||||
|
|
||||||
# main search methods and helper functions
|
# main search methods and helper functions
|
||||||
|
|
||||||
|
|
@ -267,16 +262,23 @@ class ObjectManager(TypedObjectManager):
|
||||||
if not ostring and ostring != 0:
|
if not ostring and ostring != 0:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
# Convenience check to make sure candidates are really dbobjs
|
||||||
|
if candidates:
|
||||||
|
candidates = [cand.dbobj for cand in make_iter(candidates) if hasattr(cand, "dbobj")]
|
||||||
|
|
||||||
|
# If candidates is given as an empty list, don't go any further.
|
||||||
|
if candidates == []:
|
||||||
|
return []
|
||||||
|
|
||||||
dbref = not attribute_name and self.dbref(ostring)
|
dbref = not attribute_name and self.dbref(ostring)
|
||||||
if dbref or dbref == 0:
|
if dbref or dbref == 0:
|
||||||
# Easiest case - dbref matching (always exact)
|
# Easiest case - dbref matching (always exact)
|
||||||
dbref_match = self.dbref_search(dbref)
|
dbref_match = self.dbref_search(dbref)
|
||||||
if dbref_match:
|
if dbref_match:
|
||||||
return [dbref_match]
|
if candidates == None or dbref_match.dbobj in candidates:
|
||||||
|
return [dbref_match]
|
||||||
# Convenience check to make sure candidates are really dbobjs
|
else:
|
||||||
if candidates:
|
return []
|
||||||
candidates = [cand.dbobj for cand in make_iter(candidates) if hasattr(cand, "dbobj")]
|
|
||||||
|
|
||||||
# Search through all possibilities.
|
# Search through all possibilities.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue