Подтвердить что ты не робот

Отключить метод в 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)
4b9b3361

Ответ 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']