Отключить метод в ViewSet, django-rest-framework
ViewSets
имеют автоматические методы для списка, получения, создания, обновления, удаления,...
Я хотел бы отключить некоторые из них, и решение, которое я придумал, вероятно, не очень хорошее, поскольку OPTIONS
все еще утверждает, что это разрешено.
Любая идея о том, как правильно это сделать?
class SampleViewSet(viewsets.ModelViewSet):
queryset = api_models.Sample.objects.all()
serializer_class = api_serializers.SampleSerializer
def list(self, request):
return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)
def create(self, request):
return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)
Ответы
Ответ 1
Определение ModelViewSet
:
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet)
Итак, вместо того, чтобы расширять ModelViewSet
, почему бы просто не использовать все, что вам нужно? Так, например:
from rest_framework import viewsets, mixins
class SampleViewSet(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet):
...
При таком подходе маршрутизатор должен генерировать маршруты для включенных методов.
Ссылка
ModelViewSet
Ответ 2
Вы можете продолжать использовать viewsets.ModelViewSet
и определять http_method_names
в своем ViewSet.
Пример
class SampleViewSet(viewsets.ModelViewSet):
queryset = api_models.Sample.objects.all()
serializer_class = api_serializers.SampleSerializer
http_method_names = ['get', 'post', 'head']
Как только вы добавите http_method_names
, вы больше не сможете выполнять put
и patch
.
Если вы хотите put
, но не хотите patch
, вы можете оставить http_method_names = ['get', 'post', 'head', 'put']
Внутренне, DRF Views простирается от Django CBV. У Django CBV есть атрибут с именем http_method_names. Таким образом, вы также можете использовать http_method_names с представлениями DRF.
[Бесстыдный плагин]: Если этот ответ был полезен, вам понравятся мои серии постов на DRF на https://www.agiliq.com/blog/2019/04/drf-polls/.
Ответ 3
Если вы пытаетесь отключить метод PUT из вида просмотра DRF, вы можете создать настраиваемый маршрутизатор:
from rest_framework.routers import DefaultRouter
class NoPutRouter(DefaultRouter):
"""
Router class that disables the PUT method.
"""
def get_method_map(self, viewset, method_map):
bound_methods = super().get_method_map(viewset, method_map)
if 'put' in bound_methods.keys():
del bound_methods['put']
return bound_methods
Отключив метод на маршрутизаторе, ваша документация схемы api будет правильной.
Ответ 4
Как отключить метод "УДАЛИТЬ" для ViewSet в DRF
class YourViewSet(viewsets.ModelViewSet):
def _allowed_methods(self):
return [m for m in super(YourViewSet, self)._allowed_methods() if m not in ['DELETE']]
P.S. Это более надежно, чем явное указание всех необходимых методов, поэтому меньше шансов забыть некоторые важные методы OPTIONS, HEAD и т.д.
P.P.S.
по умолчанию DRF имеет http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']