mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Modifies filter chain to use Q objects.
This commit is contained in:
parent
a6f5cccdfa
commit
fe99edd611
1 changed files with 28 additions and 10 deletions
|
|
@ -5,7 +5,7 @@ all Attributes and TypedObjects).
|
|||
|
||||
"""
|
||||
import shlex
|
||||
from django.db.models import Q
|
||||
from django.db.models import Q, Count
|
||||
from evennia.utils import idmapper
|
||||
from evennia.utils.utils import make_iter, variable_from_module
|
||||
from evennia.typeclasses.attributes import Attribute
|
||||
|
|
@ -236,7 +236,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
"""
|
||||
return self.get_tag(key=key, category=category, obj=obj, tagtype="alias")
|
||||
|
||||
def get_by_tag(self, key=None, category=None, tagtype=None):
|
||||
def get_by_tag(self, key=None, category=None, tagtype=None, **kwargs):
|
||||
"""
|
||||
Return objects having tags with a given key or category or combination of the two.
|
||||
Also accepts multiple tags/category/tagtype
|
||||
|
|
@ -250,7 +250,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
tagtype (str, optional): 'type' of Tag, by default
|
||||
this is either `None` (a normal Tag), `alias` or
|
||||
`permission`. This always apply to all queried tags.
|
||||
|
||||
|
||||
Returns:
|
||||
objects (list): Objects with matching tag.
|
||||
|
||||
|
|
@ -261,6 +261,10 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
"""
|
||||
if not (key or category):
|
||||
return []
|
||||
|
||||
global _Tag
|
||||
if not _Tag:
|
||||
from evennia.typeclasses.models import Tag as _Tag
|
||||
|
||||
keys = make_iter(key) if key else []
|
||||
categories = make_iter(category) if category else []
|
||||
|
|
@ -271,7 +275,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
query = (
|
||||
self.filter(db_tags__db_tagtype__iexact=tagtype, db_tags__db_model__iexact=dbmodel)
|
||||
.distinct()
|
||||
.order_by("id")
|
||||
#.order_by("id")
|
||||
)
|
||||
|
||||
if n_keys > 0:
|
||||
|
|
@ -286,16 +290,30 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
"get_by_tag needs a single category or a list of categories "
|
||||
"the same length as the list of tags."
|
||||
)
|
||||
|
||||
clauses = Q()
|
||||
for ikey, key in enumerate(keys):
|
||||
query = query.filter(
|
||||
db_tags__db_key__iexact=key, db_tags__db_category__iexact=categories[ikey]
|
||||
)
|
||||
# Keep each key and category together, grouped by AND
|
||||
clause = Q(db_key__iexact=key, db_category__iexact=categories[ikey])
|
||||
clauses |= clause
|
||||
|
||||
query = query.filter(db_tags__in=_Tag.objects.filter(clauses)).annotate(num_tags=Count('db_tags', distinct=True)).filter(num_tags__gte=len(keys))
|
||||
|
||||
print(keys, query.query)
|
||||
|
||||
else:
|
||||
# only one or more categories given
|
||||
for category in categories:
|
||||
query = query.filter(db_tags__db_category__iexact=category)
|
||||
clauses = Q()
|
||||
uniq_categories = sorted(set(categories))
|
||||
for category in uniq_categories:
|
||||
clause = Q(db_category__iexact=category,)
|
||||
|
||||
# Join all discrete clauses with an OR
|
||||
clauses |= clause
|
||||
|
||||
query = query.filter(db_tags__in=_Tag.objects.filter(clauses)).annotate(num_tags=Count('db_tags__db_category', distinct=True)).filter(num_tags__gte=len(uniq_categories))
|
||||
|
||||
return query
|
||||
return query.order_by('-num_tags')
|
||||
|
||||
def get_by_permission(self, key=None, category=None):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue