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)
답변
정의 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):
...
이 접근 방식을 사용하면 라우터는 포함 된 방법에 대한 경로 만 생성해야합니다.
참조 :
답변
ViewSet에서 계속 사용 viewsets.ModelViewSet
하고 정의 할 http_method_names
수 있습니다.
예
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 뷰는 Django CBV에서 확장됩니다. Django CBV에는 http_method_names라는 속성이 있습니다. 따라서 DRF보기에서도 http_method_names를 사용할 수 있습니다.
[Shameless Plug] :이 답변이 도움이 되었으면 https://www.agiliq.com/blog/2019/04/drf-polls/ 에서 DRF에 대한 내 게시물 시리즈를 좋아할 것입니다 .
답변
이 게시물은 오래되었지만 실제로는 이러한 기능을 비활성화하는 방법이라는 것을 갑자기 발견했습니다. views.py에서 직접 편집 할 수 있습니다.
출처 : https://www.django-rest-framework.org/api-guide/viewsets/#viewset-actions
from rest_framework import viewsets, status
from rest_framework.response import Response
class NameWhateverYouWantViewSet(viewsets.ModelViewSet):
def create(self, request):
response = {'message': 'Create function is not offered in this path.'}
return Response(response, status=status.HTTP_403_FORBIDDEN)
def update(self, request, pk=None):
response = {'message': 'Update function is not offered in this path.'}
return Response(response, status=status.HTTP_403_FORBIDDEN)
def partial_update(self, request, pk=None):
response = {'message': 'Update function is not offered in this path.'}
return Response(response, status=status.HTTP_403_FORBIDDEN)
def destroy(self, request, pk=None):
response = {'message': 'Delete function is not offered in this path.'}
return Response(response, status=status.HTTP_403_FORBIDDEN)
답변
DRF 뷰셋에서 PUT 메서드를 비활성화하려는 경우 사용자 지정 라우터를 만들 수 있습니다.
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 스키마 문서가 올 바릅니다.
답변
DRF에서 ViewSet에 대한 “DELETE”메서드를 비활성화하는 방법
class YourViewSet(viewsets.ModelViewSet):
def _allowed_methods(self):
return [m for m in super(YourViewSet, self)._allowed_methods() if m not in ['DELETE']]
PS 이것은 필요한 모든 메소드를 명시 적으로 지정하는 것보다 더 신뢰할 수 있으므로 OPTIONS, HEAD 등의 중요한 메소드를 잊어 버릴 가능성이 적습니다.
기본적으로 PPS DRF는 http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
답변
Django Rest Framework 3.xx ModelViewSet
에서는 사전을 as_view
메서드 에 전달하여 활성화하려는 모든 메서드를 간단히 활성화 할 수 있습니다 . 이 사전에서 키는 요청 유형 (GET, POST, DELETE 등)을 포함해야하며 값은 해당 메소드 이름 (목록, 검색, 업데이트 등)을 포함해야합니다. 예를 들어 Sample
모델을 만들거나 읽지 만 수정하고 싶지 않다고 가정 해 보겠습니다 . 당신이 원하는 의미 그래서 list
, retrieve
및 create
방법은 활성화 될 (그리고 당신이 비활성화로 다른 사람을 원한다.)
urlpatterns
다음과 같은 경로를 추가하기 만하면됩니다 .
path('sample/', SampleViewSet.as_view({
'get': 'list',
'post': 'create'
})),
path('sample/<pk>/', SampleViewSet.as_view({ # for get sample by id.
'get': 'retrieve'
}))
보시다시피 위의 라우팅 설정 에는 no delete
and put
request가 없으므로 예를 들어 put
URL에 요청을 보내면 405로 응답합니다 Method Not Allowed
.
{
"detail": "Method \"PUT\" not allowed."
}
답변
put / post / destroy 메서드를 비활성화하려는 경우 다음을 사용할 수 있습니다.
viewsets.ReadOnlyModelViewSet
https://www.django-rest-framework.org/tutorial/6-viewsets-and-routers/#refactoring-to-use-viewsets