mirror of
https://github.com/evennia/evennia.git
synced 2026-04-02 14:07:16 +02:00
Fix attribute serializer, add name filter
This commit is contained in:
parent
1153433a2c
commit
75812dcdd5
2 changed files with 56 additions and 4 deletions
|
|
@ -6,6 +6,7 @@ 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.rest_framework.filterset import FilterSet
|
||||
from django_filters.filters import CharFilter, EMPTY_VALUES
|
||||
|
|
@ -15,6 +16,19 @@ from evennia.accounts.models import AccountDB
|
|||
from evennia.scripts.models import ScriptDB
|
||||
|
||||
|
||||
def get_tag_query(tag_type: Union[str, None], key: str) -> Q:
|
||||
"""
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class TagTypeFilter(CharFilter):
|
||||
"""
|
||||
This class lets you create different filters for tags of a specified db_tagtype.
|
||||
|
|
@ -26,7 +40,7 @@ class TagTypeFilter(CharFilter):
|
|||
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(Q(db_tags__db_tagtype=self.tag_type) & Q(db_tags__db_key=value))
|
||||
return qs.filter(get_tag_query(self.tag_type, value)).distinct()
|
||||
|
||||
|
||||
class AliasFilter(TagTypeFilter):
|
||||
|
|
@ -46,6 +60,22 @@ class BaseTypeclassFilterSet(FilterSet):
|
|||
"""A parent class with filters for aliases and permissions"""
|
||||
alias = AliasFilter(lookup_expr="iexact")
|
||||
permission = PermissionFilter(lookup_expr="iexact")
|
||||
name = CharFilter(lookup_expr="iexact", method="filter_name", field_name="db_key")
|
||||
|
||||
def filter_name(self, queryset, name, value):
|
||||
"""
|
||||
|
||||
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()
|
||||
|
||||
|
||||
class ObjectDBFilterSet(BaseTypeclassFilterSet):
|
||||
|
|
@ -58,6 +88,8 @@ class ObjectDBFilterSet(BaseTypeclassFilterSet):
|
|||
|
||||
class AccountDBFilterSet(BaseTypeclassFilterSet):
|
||||
"""This adds filters for Account objects"""
|
||||
name = CharFilter(lookup_expr="iexact", method="filter_name", field_name="username")
|
||||
|
||||
class Meta:
|
||||
model = AccountDB
|
||||
fields = SHARED_FIELDS + ["username", "db_is_connected", "db_is_bot"]
|
||||
|
|
|
|||
|
|
@ -19,9 +19,26 @@ from evennia.typeclasses.tags import Tag
|
|||
|
||||
|
||||
class AttributeSerializer(serializers.ModelSerializer):
|
||||
value_display = serializers.SerializerMethodField(source="value")
|
||||
db_value = serializers.CharField(write_only=True, required=False)
|
||||
|
||||
class Meta:
|
||||
model = Attribute
|
||||
fields = ["db_key", "db_value", "db_category", "db_attrtype"]
|
||||
fields = ["db_key", "db_category", "db_attrtype", "value_display", "db_value"]
|
||||
|
||||
@staticmethod
|
||||
def get_value_display(obj: Attribute) -> str:
|
||||
"""
|
||||
Gets the string display of an Attribute's value for serialization
|
||||
Args:
|
||||
obj: Attribute being serialized
|
||||
|
||||
Returns:
|
||||
The Attribute's value in string format
|
||||
"""
|
||||
if obj.db_strvalue:
|
||||
return obj.db_strvalue
|
||||
return str(obj.value)
|
||||
|
||||
|
||||
class TagSerializer(serializers.ModelSerializer):
|
||||
|
|
@ -41,9 +58,9 @@ class TypeclassSerializerMixin(object):
|
|||
might note that the methods and fields are defined here, but they're included explicitly in each child
|
||||
class. What gives? It's a DRF error: serializer method fields which are inherited do not resolve correctly
|
||||
in child classes, and as of this current version (3.11) you must have them in the child classes explicitly
|
||||
to avoid field errors.
|
||||
to avoid field errors. Similarly, the child classes must contain the attribute serializer explicitly to
|
||||
not have them render PK-related fields.
|
||||
"""
|
||||
db_attributes = AttributeSerializer(many=True)
|
||||
|
||||
shared_fields = ["id", "db_key", "db_attributes", "db_typeclass_path", "aliases", "tags", "permissions"]
|
||||
|
||||
|
|
@ -82,6 +99,7 @@ class TypeclassSerializerMixin(object):
|
|||
|
||||
|
||||
class ObjectDBSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
||||
db_attributes = AttributeSerializer(many=True, read_only=True)
|
||||
contents = serializers.SerializerMethodField()
|
||||
exits = serializers.SerializerMethodField()
|
||||
tags = serializers.SerializerMethodField()
|
||||
|
|
@ -120,6 +138,7 @@ class ObjectDBSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
|||
|
||||
class AccountSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
||||
"""This uses the DefaultAccount object to have access to the sessions property"""
|
||||
db_attributes = AttributeSerializer(many=True, read_only=True)
|
||||
db_key = serializers.CharField(required=False)
|
||||
session_ids = serializers.SerializerMethodField()
|
||||
tags = serializers.SerializerMethodField()
|
||||
|
|
@ -144,6 +163,7 @@ class AccountSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
|||
|
||||
|
||||
class ScriptDBSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
||||
db_attributes = AttributeSerializer(many=True, read_only=True)
|
||||
tags = serializers.SerializerMethodField()
|
||||
aliases = serializers.SerializerMethodField()
|
||||
permissions = serializers.SerializerMethodField()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue