Fix regression in Tag querying when only having one category

This commit is contained in:
Griatch 2019-12-20 18:50:55 +01:00
parent edff348d87
commit 8685de3c56
3 changed files with 30 additions and 16 deletions

View file

@ -246,7 +246,7 @@ class CmdMail(default_cmds.MuxAccountCommand):
else: else:
raise IndexError raise IndexError
except IndexError: except IndexError:
self.caller.msg("Message does not exixt.") self.caller.msg("Message does not exist.")
except ValueError: except ValueError:
self.caller.msg( self.caller.msg(
"Usage: @mail/forward <account list>=<#>[/<Message>]" "Usage: @mail/forward <account list>=<#>[/<Message>]"

View file

@ -258,19 +258,21 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
Args: Args:
key (str or list, optional): Tag key or list of keys. Not case sensitive. key (str or list, optional): Tag key or list of keys. Not case sensitive.
category (str or list, optional): Tag category. Not case sensitive. If `key` is category (str or list, optional): Tag category. Not case sensitive.
a list, a single category can either apply to all keys in that list or this If `key` is a list, a single category can either apply to all
must be a list matching the `key` list element by element. If no `key` is given, keys in that list or this must be a list matching the `key`
all objects with tags of this category are returned. list element by element. If no `key` is given, all objects with
tags of this category are returned.
tagtype (str, optional): 'type' of Tag, by default tagtype (str, optional): 'type' of Tag, by default
this is either `None` (a normal Tag), `alias` or this is either `None` (a normal Tag), `alias` or `permission`.
`permission`. This always apply to all queried tags. This always apply to all queried tags.
Kwargs: Kwargs:
match (str): ALL or ANY, determines whether the target object must match match (str): "all" (default) or "any"; determines whether the
ALL of the provided tags/categories or ANY single one. ANY will perform target object must be tagged with ALL of the provided
a weighted sort, so objects with more tag matches will outrank those tags/categories or ANY single one. ANY will perform a weighted
with fewer tag matches. sort, so objects with more tag matches will outrank those with
fewer tag matches.
Returns: Returns:
objects (list): Objects with matching tag. objects (list): Objects with matching tag.
@ -293,6 +295,8 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
categories = make_iter(category) if category else [] categories = make_iter(category) if category else []
n_keys = len(keys) n_keys = len(keys)
n_categories = len(categories) n_categories = len(categories)
unique_categories = sorted(set(categories))
n_unique_categories = len(unique_categories)
dbmodel = self.model.__dbclass__.__name__.lower() dbmodel = self.model.__dbclass__.__name__.lower()
query = ( query = (
@ -322,9 +326,9 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
else: else:
# only one or more categories given # only one or more categories given
# import evennia;evennia.set_trace()
clauses = Q() clauses = Q()
uniq_categories = sorted(set(categories)) for category in unique_categories:
for category in uniq_categories:
clauses |= Q(db_category__iexact=category) clauses |= Q(db_category__iexact=category)
tags = _Tag.objects.filter(clauses) tags = _Tag.objects.filter(clauses)
@ -334,7 +338,8 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
# Default ALL: Match all of the tags and optionally more # Default ALL: Match all of the tags and optionally more
if match == "all": if match == "all":
query = query.filter(matches__gte=tags.count()) n_req_tags = tags.count() if n_keys > 0 else n_unique_categories
query = query.filter(matches__gte=n_req_tags)
# ANY: Match any single tag, ordered by weight # ANY: Match any single tag, ordered by weight
elif match == "any": elif match == "any":
query = query.order_by("-matches") query = query.order_by("-matches")

View file

@ -80,6 +80,9 @@ class TestTypedObjectManager(EvenniaTest):
self.obj2.tags.add("tag6", "category3") self.obj2.tags.add("tag6", "category3")
self.obj2.tags.add("tag7", "category1") self.obj2.tags.add("tag7", "category1")
self.obj2.tags.add("tag7", "category5") self.obj2.tags.add("tag7", "category5")
self.obj1.tags.add("tag8", "category6")
self.obj2.tags.add("tag9", "category6")
self.assertEqual( self.assertEqual(
self._manager("get_by_tag", "tag5", "category1"), [self.obj1, self.obj2] self._manager("get_by_tag", "tag5", "category1"), [self.obj1, self.obj2]
) )
@ -105,8 +108,14 @@ class TestTypedObjectManager(EvenniaTest):
) )
self.assertEqual( self.assertEqual(
self._manager("get_by_tag", category=["category1", "category2"]), self._manager("get_by_tag", category=["category1", "category2"]),
[self.obj2], [self.obj1, self.obj2],
) )
self.assertEqual( self.assertEqual(
self._manager("get_by_tag", category=["category5", "category4"]), [] self._manager("get_by_tag", category=["category5", "category4"]), []
) )
self.assertEqual(
self._manager("get_by_tag", category="category1"), [self.obj1, self.obj2]
)
self.assertEqual(
self._manager("get_by_tag", category="category6"), [self.obj1, self.obj2]
)