from knox.auth import TokenAuthentication from rest_framework.viewsets import GenericViewSet from rest_framework.generics import GenericAPIView from rest_framework.response import Response from rest_framework.viewsets import ViewSetMixin from rest_framework.decorators import action from rest_framework.renderers import BrowsableAPIRenderer from rest_framework.renderers import JSONRenderer from rest_framework_yaml.renderers import YAMLRenderer from rest_framework_xml.renderers import XMLRenderer from settings.puckomissions import IsAdminOrReadOnly from settings.puckignation import MediumPagination class PuckoView(GenericViewSet, ViewSetMixin): authentication_classes = (TokenAuthentication,) renderer_classes = (BrowsableAPIRenderer, JSONRenderer, YAMLRenderer, XMLRenderer) class PuckoPagesView(PuckoView): pagination_class = MediumPagination def get_queryset(self, request=None): return self.model_class.objects.all() def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset(request=request)) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) def get_paginated_response(self, data, status=200): """ Return a paginated style `Response` object for the given output data. """ assert self.paginator is not None return self.paginator.get_paginated_response(data, status=200) def get_paginated_response_schema(self, *args, **kwargs): assert self.paginator is not None return self.paginator.get_paginated_response_schema(*args, **kwargs) class PuckoPaginatedView(PuckoPagesView): def __init__(self, *args, **kwargs): super(PuckoPaginatedView).__init__(*args, **kwargs) @action(detail=False) def fetch_all(self, request): query = self.paginator.paginate_queryset(self.get_queryset(), request) serializer = self.serializer_class(query, many=True) return self.get_paginated_response(serializer.data, status=200) class PuckoSearchView(PuckoPagesView): @action(detail=False) def list(self, request): serializer = self.serializer_class(data=request.data, many=False) data = serializer.initial_data if serializer.is_valid(): data = self.paginator.paginate_queryset(self.get_object(data), request) ret = self.serializer_class(data, many=True) if len(ret.data) < 1: return Response({"message": "Could not find anything"}, status="404") return self.get_paginated_response(ret.data, status=200) return Response({"message": "not a valid search."}, status=400) class PuckoAddView(PuckoView): @action(detail=True) def create(self, request): serializer = self.serializer_class(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=201) return Response(serializer.errors, status=400) class PuckoAllAddView(PuckoPaginatedView, PuckoAddView): pass class PuckoSlugView(PuckoView): permission_classes = (IsAdminOrReadOnly,) def get_object(self, slug): try: return self.model_class.objects.get(slug=slug) except: return Response({"message": f"{self.model_class.__class__.__name__} could not be found."}) @action(detail=True) def retrieve(self, request, slug): obj = self.get_object(slug) if isinstance(obj, Response): return obj serializer = self.serializer_class(obj) return Response(serializer.data, status=200) @action(detail=True) def update(self, request, slug): obj = self.get_object(slug) if isinstance(obj, Response): return obj serializer = self.serializer_class(obj, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=201) return Response(serializer.errors, status=400) @action(detail=True) def update_partial(self, request, slug): obj = self.get_object(slug) if isinstance(obj, Response): return obj serializer = self.serializer_class(obj, data=request.data, partial=True) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=201) return Response(serializer.errors, status=400) @action(detail=True) def delete(self, request, slug): obj = self.get_object(slug) if isinstance(obj, Response): return obj if obj is None: return Response({"message", "could not delete, what i could not find."}) obj.delete() return Response({"message": f"{obj.__class__.__name__} deleted."}, status=204)