diff --git a/settings/puckoviews.py b/settings/puckoviews.py new file mode 100644 index 0000000..b9a1672 --- /dev/null +++ b/settings/puckoviews.py @@ -0,0 +1,133 @@ +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) + serializer_class = None + model_class = None + +class PuckoPagesView(PuckoView): + pagination_class = MediumPagination + + def get_queryset(self): + return self.model_class.objects.all() + + def list(self, request, *args, **kwargs): + queryset = self.filter_queryset(self.get_queryset()) + + 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)