Source code for evennia.web.api.views
"""
Views are the functions that are called by different url endpoints. The Django
Rest Framework provides collections called 'ViewSets', which can generate a
number of views for the common CRUD operations.
"""
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from evennia.accounts.models import AccountDB
from evennia.help.models import HelpEntry
from evennia.objects.models import ObjectDB
from evennia.objects.objects import DefaultCharacter, DefaultExit, DefaultRoom
from evennia.scripts.models import ScriptDB
from evennia.web.api import filters, serializers
from evennia.web.api.permissions import EvenniaPermission
[docs]class GeneralViewSetMixin:
"""
Mixin for both typeclass- and non-typeclass entities.
"""
[docs] def get_serializer_class(self):
"""
Allow different serializers for certain actions.
"""
if self.action == "list":
if hasattr(self, "list_serializer_class"):
return self.list_serializer_class
return self.serializer_class
[docs]class TypeclassViewSetMixin(GeneralViewSetMixin):
"""
This mixin adds some shared functionality to each viewset of a typeclass. They all use the same
permission classes and filter backend. You can override any of these in your own viewsets.
The `set_atribute` action is an example of a custom action added to a
viewset. Based on the name of the method, it will create a default url_name
(used for reversing) and url_path. The 'pk' argument is automatically
passed to this action because it has a url path of the format <object
type>/:pk/set-attribute. The get_object method is automatically set in the
expected viewset classes that will inherit this, using the pk that's passed
along to retrieve the object.
"""
# permission classes determine who is authorized to call the view
permission_classes = [EvenniaPermission]
# the filter backend allows for retrieval views to have filter arguments passed to it,
# for example: mygame.com/api/objects?db_key=bob to find matches based on objects having a db_key of bob
filter_backends = [DjangoFilterBackend]
[docs] @action(detail=True, methods=["put", "post"])
def set_attribute(self, request, pk=None):
"""
This action will set an attribute if the db_value is defined, or remove
it if no db_value is provided.
"""
attr = serializers.AttributeSerializer(data=request.data)
obj = self.get_object()
if attr.is_valid(raise_exception=True):
key = attr.validated_data["db_key"]
value = attr.validated_data.get("db_value")
category = attr.validated_data.get("db_category")
attr_type = attr.validated_data.get("db_attrtype")
if attr_type == "nick":
handler = obj.nicks
else:
handler = obj.attributes
if value:
handler.add(key=key, value=value, category=category)
else:
handler.remove(key=key, category=category)
return Response(
serializers.AttributeSerializer(obj.db_attributes.all(), many=True).data,
status=status.HTTP_200_OK,
)
return Response(attr.errors, status=status.HTTP_400_BAD_REQUEST)
[docs]class ObjectDBViewSet(TypeclassViewSetMixin, ModelViewSet):
"""
The Object is the parent for all in-game entities that have a location
(rooms, exits, characters etc).
"""
# An example of a basic viewset for all ObjectDB instances. It declares the
# serializer to use for both retrieving and changing/creating/deleting
# instances. Serializers are similar to django forms, used for the
# transmitting of data (typically json).
serializer_class = serializers.ObjectDBSerializer
queryset = ObjectDB.objects.all()
filterset_class = filters.ObjectDBFilterSet
list_serializer_class = serializers.ObjectListSerializer
[docs]class CharacterViewSet(ObjectDBViewSet):
"""
Characters are a type of Object commonly used as player avatars in-game.
"""
queryset = DefaultCharacter.objects.all_family()
[docs]class RoomViewSet(ObjectDBViewSet):
"""
Rooms indicate discrete locations in-game.
"""
queryset = DefaultRoom.objects.all_family()
[docs]class ExitViewSet(ObjectDBViewSet):
"""
Exits are objects with a destination and allows for traversing from one
location to another.
"""
queryset = DefaultExit.objects.all_family()
[docs]class AccountDBViewSet(TypeclassViewSetMixin, ModelViewSet):
"""
Accounts represent the players connected to the game
"""
serializer_class = serializers.AccountSerializer
queryset = AccountDB.objects.all()
filterset_class = filters.AccountDBFilterSet
list_serializer_class = serializers.AccountListSerializer
[docs]class ScriptDBViewSet(TypeclassViewSetMixin, ModelViewSet):
"""
Scripts are meta-objects for storing system data, running timers etc. They
have no in-game existence.
"""
serializer_class = serializers.ScriptDBSerializer
queryset = ScriptDB.objects.all()
filterset_class = filters.ScriptDBFilterSet
list_serializer_class = serializers.ScriptListSerializer
[docs]class HelpViewSet(GeneralViewSetMixin, ModelViewSet):
"""
Database-stored help entries.
Note that command auto-help and file-based help entries are not accessible this way.
"""
serializer_class = serializers.HelpSerializer
queryset = HelpEntry.objects.all()
filterset_class = filters.HelpFilterSet
list_serializer_class = serializers.HelpListSerializer