Ich persönlich hasse diese Art von frankenmonster benutzerdefinierten Berechtigungen, meiner Meinung nach, ist es nicht sehr idiomatisch ist, wenn es um Django Framework kommt; Also kam ich auf die folgende Lösung - es ist sehr ähnlich wie @list_route und @detail_route Dekoratoren arbeiten. Wir verlassen uns auf die Tatsache, dass die Methoden/Funktionen sind erstklassige Objekte
Als erstes habe ich solche dectorator bin erstellen:
decorators.py
def route_action_arguments(**kwargs):
"""
Add arguments to the action method
"""
def decorator(func):
func.route_action_kwargs = kwargs
return func
return decorator
Wie Sie sehen können es fügt ein Wörterbuch der Funktion hinzu, die es mit Parametern schmückt, die als arg-Liste
überreicht werden. Jetzt schuf ich solch ein mixin: mixins. py
class RouteActionArgumentsMixin (object):
"""
Use action specific parameters to
provide:
- serializer
- permissions
"""
def _get_kwargs(self):
action = getattr(self, 'action')
if not action:
raise AttributeError
print('getting route kwargs for action:' + action)
action_method = getattr(self, action)
kwargs = getattr(action_method, 'route_action_kwargs')
print(dir(kwargs))
return kwargs
def get_serializer_class(self):
try:
kwargs = self._get_kwargs()
return kwargs['serializer']
except (KeyError, AttributeError):
return super(RouteActionArgumentsMixin, self).get_serializer_class()
def get_permissions(self):
try:
kwargs = self._get_kwargs()
return kwargs['permission_classes']
except (KeyError, AttributeError):
return super(RouteActionArgumentsMixin, self).get_permissions()
Mixin macht zwei Dinge; wenn get_permissions aufgerufen wird, überprüft er die ‚Aktion‘ ausgeführt wird, und die looksup permission_classes Sammlung aus der mit den viewset.action_method.route_action_kwargs ‚route_action_kwargs‘ zugeordnet
wenn get_serializer_class genannt wird, tut es das gleiche und nimmt die " Serializer‘von‚
Now‘route_action_kwargs die Art und Weise können wir es verwenden:
@method_decorator(route_action_arguments(serializer=LoginSerializer), name='create')
class UserViewSet (RouteActionArgumentsMixin, RequestContextMixin, viewsets.ModelViewSet):
"""
User and profile managment viewset
"""
queryset = User.objects.all()
serializer_class = UserSerializer
@list_route(methods=['post'])
@route_action_arguments(permission_classes=(AllowAny,), serializer=LoginSerializer)
def login(self, request):
serializer = self.get_serializer_class()(data=request.data)
Für benutzerdefinierte routse wir explizit definieren, können wir die @route_action_arguments explizit auf der Methode nur.
Im Hinblick auf den allgemeinen Viewset und Methoden, können wir sie noch hinzufügen, um den @method_decorator mit
@method_decorator(route_action_arguments(serializer=LoginSerializer), name='create')
class UserViewSet (RouteActionArgumentsMixin, RequestContextMixin, viewsets.ModelViewSet):
django.contrib.auth den Dekorateure sind nicht immer nützlich, wenn DRF generische Ansichten verwenden. Ziemlich oft implementieren Sie die HTTP-Methoden überhaupt nicht - es gibt also nichts zu dekorieren. (Und sie zu implementieren oder zu versenden, nur um sie zu dekorieren, macht keinen Spaß.) In diesem Fall ist es besser, DRFs eigenes Berechtigungssystem zu verwenden. http://django-rest-framework.org/api-guide/permissions.html –