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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 03:16:07  来源:igfitidea点击:

Disable a method in a ViewSet, django-rest-framework

pythondjangodjango-viewsdjango-rest-framework

提问by db0

ViewSetshave 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 OPTIONSstill 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 ModelViewSetis:

的定义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:

参考

ModelViewSet

模型视图集

回答by Akshar Raaj

You could keep using viewsets.ModelViewSetand define http_method_nameson 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 putand patchanymore.

一旦你加入http_method_names,你将无法做到putpatch了。

If you want putbut 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_viewmethod. For example let say you want Samplemodel to be created or read but you don't want it to be modified. So it means you want list, retrieveand createmethod to be enable (and you want others to be disabled.)

在 Django Rest Framework 3.xx 中,您可以通过将字典传递给as_view方法来简单地启用您想要的每个方法。例如,假设您希望Sample创建或读取模型,但不希望修改它。所以这意味着您希望list,retrievecreate方法被启用(并且您希望其他人被禁用。)

All you need to do is to add paths to urlpatternslike 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 deleteand putrequest in above routing settings, so for example if you send a putrequest to the url, it response you with 405 Method Not Allowed:

如您所见,上述路由设置中没有deleteput请求,例如,如果您向puturl发送请求,它会以 405 响应您Method Not Allowed

{
    "detail": "Method \"PUT\" not allowed."
}