Last active
November 24, 2019 20:20
-
-
Save ivlevdenis/a0c8f5b472b6b8550bbb016c6a30e0be to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rest_framework import viewsets | |
from rest_framework.response import Response | |
# https://gist.github.com/ivlevdenis/a0c8f5b472b6b8550bbb016c6a30e0be | |
class ExtendViewSet(object): | |
""" | |
This viewset mixin class with extended options list. | |
""" | |
permission_map = {} | |
throttle_scope_map = {} | |
serializer_class_map = {} | |
def get_serializer_class(self): | |
ser = self.serializer_class_map.get(self.action, None) | |
self.serializer_class = ser or self.serializer_class | |
return super().get_serializer_class() | |
def initialize_request(self, request, *args, **kwargs): | |
request = super().initialize_request(request, *args, **kwargs) | |
throttle_scope = self.throttle_scope_map.get(self.action, None) | |
cls_throttle_scope = getattr(self, 'throttle_scope', None) | |
self.throttle_scope = throttle_scope or cls_throttle_scope or '' | |
return request | |
def get_permissions(self): | |
perms = self.permission_map.get(self.action, None) | |
if perms and not isinstance(perms, (tuple, list)): | |
perms = [perms, ] | |
self.permission_classes = perms or self.permission_classes | |
return super().get_permissions() | |
def options(self, request, *args, **kwargs): | |
if self.metadata_class is None: | |
return self.http_method_not_allowed(request, *args, **kwargs) | |
data = self.metadata_class().determine_metadata(request, self) | |
data['actions']['GET'] = self.query_metadata | |
return Response(data, status=status.HTTP_200_OK) | |
class ExtendedModelViewSet(ExtendViewSet, viewsets.ModelViewSet): | |
""" | |
Examples: | |
class MyModelViewSet(ExtendedModelViewSet): | |
serializer_class_map = { | |
'list': ListMyModelSerializer, | |
'retrieve': RetrieveMyModelSerializer, | |
'update': UpdateMyModelSerializer, | |
... | |
} | |
""" | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I find it easy to accidentally type the wrong action name into one of the mappings.
For example, I might type "delete" instead of "destroy" in the
permission_map
. If you do this, then you've just silently opened your HTTP DELETE to everyone.I added some checks for valid actions (including custom actions) in my fork of this gist.