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)
의 정의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):
...
이 방법을 사용하면 라우터는 포함된 메서드에 대한 경로만 생성해야 합니다.
참조:
업데이트: DRF 3.14.0에서 믹스인에 구현되지 않은 방법 중 하나를 사용하면405 - Method Not Allowed
:
Method Not Allowed: /status/
[06/Mar/2023 01:03:01] "POST /status/ HTTP/1.1" 405 41
계속 사용할 수 있습니다.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 Views는 Django CBV에서 확장됩니다.장고 CBV에는 http_method_names라는 특성이 있습니다.따라서 DRF 보기에도 http_method_names를 사용할 수 있습니다.
[뻔뻔한 플러그]:이 답변이 도움이 되었다면 DRF(https://www.agiliq.com/blog/2019/04/drf-polls/ )에 제가 올린 일련의 게시물을 좋아하시게 될 것입니다.
이 게시물을 올린 지 오래되었지만, 저는 갑자기 이러한 기능을 비활성화하는 방법이 있다는 것을 알게 되었습니다. views.py 에서 직접 편집할 수 있습니다.
출처: https://www.django-rest-framework.org/api-guide/viewsets/ #viewset-message
from rest_framework import viewsets, status
from rest_framework.response import Response
class NameThisClassWhateverYouWantViewSet(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 스키마 문서가 정확해집니다.
저는 @pymen answer의 아이디어가 마음에 들었지만, 그의 구현은 효과가 없었습니다.이 작업은 다음과 같습니다.
class SampleViewSet(viewsets.ModelViewSet):
http_method_names = [m for m in viewsets.ModelViewSet.http_method_names if m not in ['delete']]
이것은 말 그대로 배제만 하고 단순하다는 장점이 있습니다.다소 구식으로 보이지만, ViewSet 하나만 사용할 경우에는 정확히 필요한 것일 수 있습니다.
보기 집합에서 메서드를 비활성화하고 api 전체에서 일관성을 유지하며 유용한 오류 메시지를 반환하는 가장 간단한 방법은 사용하지 않을 메서드에 대해 MethodNotAllowed 예외를 발생시키는 것입니다.목록을 검색하고 목록을 표시하지 않도록 매핑된 GET과 같은 메서드의 경우 오류 메시지를 사용자 지정하여 GET이 URL의 조회 값으로만 작동함을 나타낼 수 있습니다.
from rest_framework.exceptions import MethodNotAllowed
class SampleViewSet(viewsets.ModelViewSet):
queryset = api_models.Sample.objects.all()
serializer_class = api_serializers.SampleSerializer
def list(self, request):
raise MethodNotAllowed('GET', detail='Method "GET" not allowed without lookup')
def create(self, request):
raise MethodNotAllowed(method='POST')
그러면 DRF가 사용하는 형식의 405 상태 코드와 json 데이터가 반환됩니다.
{'detail': 'Method "POST" not allowed.'}
이것이 제가 선호하는 것입니다.
from rest_framework import viewsets, mixins
class ContentViewSet(mixins.CreateModelMixin, viewsets.ReadOnlyModelViewSet):
queryset = models.Content.objects.all()
serializer_class = serializers.ContentSerializer
ReadOnlyModelViewSet - 읽기 전용 메서드만 유지합니다.기본적으로 "GET" 및 "OPTIONS" 요청입니다.
CreateModelMixin - 새 요소만 만들 수 있습니다.그것은 "POST" 요청입니다.
위의 예에서는 "PUT", "PATH" 및 "DELETE"와 같은 다른 모든 메서드를 사용할 수 없습니다.요구 사항에 따라 믹스인을 사용하여 다양한 방법을 활성화할 수 있습니다.
DRF에서 ViewSet에 대해 "DELEATE" 메서드를 비활성화하는 방법
class YourViewSet(viewsets.ModelViewSet):
def _allowed_methods(self):
return [m for m in super(YourViewSet, self)._allowed_methods() if m not in ['DELETE']]
추신. 이것은 필요한 모든 방법을 명시적으로 명시하는 것보다 더 신뢰할 수 있으므로 OPTIONS, HEAD 등 일부 중요한 방법을 잊어버릴 가능성이 적습니다.
에는 기본적으로 가 "DRF" P.P가 있습니다.S가 있습니다.http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
3에서는 Django Rest Framework 3.x.x에 각 활성화하기만 .ModelViewSet
을 사전넘로써에 으로써.as_view
사전에서 GET,을 포함해야 하며 에는 해당 이름 retrieve을 포함해야 .이 사전에서 키에는 요청 유형(GET, POST, DELETE 등)이 포함되어야 하며 값에는 해당 메서드 이름(list, retrieve, update 등)이 포함되어야 합니다.예를 들어, 당신이 원한다고 말하겠습니다.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'
}))
것처럼 시없피다습니다보가 .delete
그리고.put
의 라우팅합니다. 를 들어, " " " 를 . 예를 들어, 다음과 같은 경우put
요청하면 URL로 합니다.Method Not Allowed
:
{
"detail": "Method \"PUT\" not allowed."
}
Put/Post/Destroy 메서드를 사용하지 않으려면 다음을 사용할 수 있습니다.
뷰 세트읽기 전용 모델 보기https://www.django-rest-framework.org/tutorial/6-viewsets-and-routers/ #refactoring-to-use-dets 설정
django-rest-framework의 Viewsets에 대한 방법을 활성화/비활성화하기 위한 대안적인 접근법입니다.다음은 api/urls.py 의 예입니다.
user_list = UserViewSet.as_view({
'get': 'list'
})
user_detail = UserViewSet.as_view({
'get': 'retrieve'
'put': 'update',
'post': 'create',
'patch': 'partial_update',
'delete': 'destroy'
})
urlpatterns = [
path('users/', user_list, name='user-list'),
path('users/<int:pk>/', user_detail, name='user-detail')
]
View user_list에는 하나의 -get - 메서드만 허용되는 반면 user_detail에는 모든 메서드가 활성화되어 있습니다.
Django 4.0에서 테스트됨
참조: 자세한 내용은 여기를 참조하십시오.
작은 장식가를 쓸 수 있습니다.
def http_methods_disable(*methods):
def decorator(cls):
cls.http_method_names = [method for method in cls.http_method_names if method not in methods]
return cls
return decorator
그런 다음 다른 클래스에서 사용할 수 있습니다.
@http_methods_disable('patch', 'delete')
class SampleViewSet(viewsets.ModelViewSet):
...
@http_methods_disable('patch')
class AnyViewSet(viewsets.ModelViewSet):
...
GenericViewSet을 사용하기만 하면 HTTP 동작을 사용하기 전에 해당 동작을 명시적으로 정의해야 합니다.자세한 내용은 이 항목을 참조하십시오.
언급URL : https://stackoverflow.com/questions/23639113/disable-a-method-in-a-viewset-django-rest-framework
'programing' 카테고리의 다른 글
그리드 레이아웃에서 제스처 감지 실행 (0) | 2023.06.05 |
---|---|
이클립스 워크스페이스:무엇 때문에 그리고 왜? (0) | 2023.06.05 |
Lazy는 언제 사용해야 합니까? (0) | 2023.06.05 |
이 예외를 어떻게 잡습니까? (0) | 2023.06.05 |
사용자 클릭 선택 구성 요소가 있는 동적 탭 (0) | 2023.05.31 |