Python 禁用 ViewSet 中的一个方法,django-rest-framework
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23639113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Disable a method in a ViewSet, django-rest-framework
提问by db0
ViewSets
have automatic methods to list, retrieve, create, update, delete, ...
ViewSets
有自动的方法来列出、检索、创建、更新、删除……
I would like to disable some of those, and the solution I came up with is probably not a good one, since OPTIONS
still states those as allowed.
我想禁用其中的一些,我想出的解决方案可能不是一个好的解决方案,因为OPTIONS
仍然声明那些是允许的。
Any idea on how to do this the right way?
关于如何以正确的方式做到这一点的任何想法?
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)
采纳答案by SunnySydeUp
The definition of ModelViewSet
is:
的定义ModelViewSet
是:
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet)
So rather than extending ModelViewSet
, why not just use whatever you need? So for example:
因此,与其扩展ModelViewSet
,为什么不直接使用您需要的任何东西?例如:
from rest_framework import viewsets, mixins
class SampleViewSet(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet):
...
With this approach, the router should only generate routes for the included methods.
使用这种方法,路由器应该只为包含的方法生成路由。
Reference:
参考:
回答by Akshar Raaj
You could keep using viewsets.ModelViewSet
and define http_method_names
on your ViewSet.
您可以继续在您的 ViewSet 上使用viewsets.ModelViewSet
和定义http_method_names
。
Example
例子
class SampleViewSet(viewsets.ModelViewSet):
queryset = api_models.Sample.objects.all()
serializer_class = api_serializers.SampleSerializer
http_method_names = ['get', 'post', 'head']
Once you add http_method_names
, you will not be able to do put
and patch
anymore.
一旦你加入http_method_names
,你将无法做到put
和patch
了。
If you want put
but don't want patch
, you can keep http_method_names = ['get', 'post', 'head', 'put']
如果你想要put
但不想要patch
,你可以保留http_method_names = ['get', 'post', 'head', 'put']
Internally, DRF Views extend from Django CBV. Django CBV has an attribute called http_method_names. So you can use http_method_names with DRF views too.
在内部,DRF 视图从 Django CBV 扩展而来。Django CBV 有一个名为 http_method_names 的属性。因此,您也可以将 http_method_names 与 DRF 视图一起使用。
[Shameless Plug]: If this answer was helpful, you will like my series of posts on DRF at https://www.agiliq.com/blog/2019/04/drf-polls/.
[无耻插件]:如果这个回答有帮助,你会喜欢我在https://www.agiliq.com/blog/2019/04/drf-polls/上的 DRF 系列帖子。
回答by storn
If you are trying to disable the PUT method from a DRF viewset, you can create a custom router:
如果您尝试从 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
By disabling the method at the router, your api schema documentation will be correct.
通过在路由器上禁用该方法,您的 api 架构文档将是正确的。
回答by pymen
How to disable "DELETE" method for ViewSet in DRF
如何在 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']]
P.S. This is more reliable than explicitly specifying all the necessary methods, so there is less chance of forgetting some of important methods OPTIONS, HEAD, etc
PS 这比明确指定所有必要的方法更可靠,因此忘记一些重要方法 OPTIONS、HEAD 等的可能性较小
P.P.S.
by default DRF has http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
PPS 默认情况下 DRF 有 http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
回答by W Kenny
Although it's been a while for this post, I suddenly found out that actually their is a way to disable those function, you can edit it in the views.py directly.
虽然这个帖子已经有一段时间了,但我突然发现他们实际上是一种禁用这些功能的方法,你可以直接在views.py中编辑它。
Source: https://www.django-rest-framework.org/api-guide/viewsets/#viewset-actions
来源: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)
回答by Hamidreza
In Django Rest Framework 3.x.x you can simply enable every each method you want by passing a dictionary to as_view
method. For example let say you want Sample
model to be created or read but you don't want it to be modified. So it means you want list
, retrieve
and create
method to be enable (and you want others to be disabled.)
在 Django Rest Framework 3.xx 中,您可以通过将字典传递给as_view
方法来简单地启用您想要的每个方法。例如,假设您希望Sample
创建或读取模型,但不希望修改它。所以这意味着您希望list
,retrieve
和create
方法被启用(并且您希望其他人被禁用。)
All you need to do is to add paths to urlpatterns
like these:
您需要做的就是添加路径,urlpatterns
如下所示:
path('sample/', SampleViewSet.as_view({
'get': 'list',
'post': 'create'
})),
path('sample/<pk>/', SampleViewSet.as_view({ # for get sample by id.
'get': 'retrieve'
}))
As you can see there's no delete
and put
request in above routing settings, so for example if you send a put
request to the url, it response you with 405 Method Not Allowed
:
如您所见,上述路由设置中没有delete
和put
请求,例如,如果您向put
url发送请求,它会以 405 响应您Method Not Allowed
:
{
"detail": "Method \"PUT\" not allowed."
}