Source code for evennia.web.api.filters
"""
FilterSets allow clients to specify querystrings that will determine the data
that is retrieved in GET requests. By default, Django Rest Framework uses the
'django-filter' package as its backend. Django-filter also has a section in its
documentation specifically regarding DRF integration.
https://django-filter.readthedocs.io/en/latest/guide/rest_framework.html
"""
from typing import Union
from django.db.models import Q
from django_filters.filters import EMPTY_VALUES, CharFilter
from django_filters.rest_framework.filterset import FilterSet
from evennia.accounts.models import AccountDB
from evennia.objects.models import ObjectDB
from evennia.scripts.models import ScriptDB
[docs]def get_tag_query(tag_type: Union[str, None], key: str) -> Q:
"""
Returns a Q object for searching by tag names for typeclasses
Args:
tag_type(str or None): The type of tag (None, 'alias', etc)
key (str): The name of the tag
Returns:
A Q object that for searching by this tag type and name
"""
return Q(db_tags__db_tagtype=tag_type) & Q(db_tags__db_key__iexact=key)
[docs]class TagTypeFilter(CharFilter):
"""
This class lets you create different filters for tags of a specified db_tagtype.
"""
tag_type = None
[docs] def filter(self, qs, value):
# if no value is specified, we don't use the filter
if value in EMPTY_VALUES:
return qs
# if they enter a value, we filter objects by having a tag of this type with the given name
return qs.filter(get_tag_query(self.tag_type, value)).distinct()
[docs]class AliasFilter(TagTypeFilter):
"""A filter for objects by their aliases (tags with a tagtype of 'alias'"""
tag_type = "alias"
[docs]class PermissionFilter(TagTypeFilter):
"""A filter for objects by their permissions (tags with a tagtype of 'permission'"""
tag_type = "permission"
SHARED_FIELDS = ["db_key", "db_typeclass_path", "db_tags__db_key", "db_tags__db_category"]
[docs]class BaseTypeclassFilterSet(FilterSet):
"""
A parent class with filters for aliases and permissions
"""
name = CharFilter(lookup_expr="iexact", method="filter_name", field_name="db_key")
alias = AliasFilter(lookup_expr="iexact")
permission = PermissionFilter(lookup_expr="iexact")
[docs] @staticmethod
def filter_name(queryset, name, value):
"""
Filters a queryset by aliases or the key of the typeclass
Args:
queryset: The queryset being filtered
name: The name of the field
value: The value passed in from GET params
Returns:
The filtered queryset
"""
query = Q(**{f"{name}__iexact": value})
query |= get_tag_query("alias", value)
return queryset.filter(query).distinct()
[docs]class ObjectDBFilterSet(BaseTypeclassFilterSet):
"""
This adds filters for ObjectDB instances - characters, rooms, exits, etc
"""
[docs]class AccountDBFilterSet(BaseTypeclassFilterSet):
"""This adds filters for Account objects"""
name = CharFilter(lookup_expr="iexact", method="filter_name", field_name="username")
[docs]class ScriptDBFilterSet(BaseTypeclassFilterSet):
"""This adds filters for Script objects"""
[docs]class HelpFilterSet(FilterSet):
"""
Filter for help entries
"""
name = CharFilter(lookup_expr="iexact", method="filter_name", field_name="db_key")
category = CharFilter(lookup_expr="iexact", method="filter_name", field_name="db_category")
alias = AliasFilter(lookup_expr="iexact")