db0*_*db0 102 python django django-views 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)
Run Code Online (Sandbox Code Playgroud)
Sun*_*eUp 214
定义ModelViewSet是:
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet)
Run Code Online (Sandbox Code Playgroud)
因此ModelViewSet,为什么不只是使用你需要的东西而不是延伸?例如:
from rest_framework import viewsets, mixins
class SampleViewSet(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet):
...
Run Code Online (Sandbox Code Playgroud)
使用这种方法,路由器应该只为包含的方法生成路由.
参考:
Aks*_*aaj 108
您可以继续在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']
Run Code Online (Sandbox Code Playgroud)
一旦你加入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视图一起使用.
W K*_*nny 16
虽然这个帖子已经有一段时间了,但我突然发现实际上有一种方法可以禁用这些功能,您可以直接在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 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)
Run Code Online (Sandbox Code Playgroud)
小智 8
如果您尝试从 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
Run Code Online (Sandbox Code Playgroud)
通过在路由器上禁用该方法,您的 api 架构文档将是正确的。
小智 6
我喜欢@pymen 答案的想法,但他的实现不起作用。这会:
class SampleViewSet(viewsets.ModelViewSet):
http_method_names = [m for m in viewsets.ModelViewSet.http_method_names if m not in ['delete']]
Run Code Online (Sandbox Code Playgroud)
这样做的优点是实际上只进行排除并且很简单。虽然它看起来有点老套,但如果它仅适用于那个 ViewSet,则可能正是您所需要的。