社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Django

Django Rest框架中的action decorator方法需要在类http_method_names中指定

James Lin • 4 年前 • 1477 次点击  

DRF版本是3.11.2

我正在编写一些现有代码,向视图集中添加一个额外的“删除”操作,但我得到了 405 Method not allowed 考虑下面的例子

class UserViewSet(ModelViewSet):
    ....
    queryset = User.objects.all()
    http_method_names = ['get', 'post']

    @action(detail=True, method=['delete'])
    def delete_profile(self, request, pk=None)
        Profile.objects.get(user=pk).delete()
        ....

就像我说的,当我调用delete方法 /user/123/delete_profile ,我明白了 405方法不允许 然而,如果我加上 delete http_method_names 如下所示,它运行良好。

class UserViewSet(ViewSet):
    ....
    queryset = User.objects.all()
    http_method_names = ['get', 'post', 'delete']

    @action(detail=True, method=['delete'])
    def delete_profile(self, request, pk=None)
        Profile.objects.get(user=pk).delete()
        ....

但这并不理想,因为我不想允许对用户执行“删除”操作,同时我可以覆盖 删去 / destroy 要避免用户在viewset上被删除,此方法非常优雅。

所以问题是,这是一个bug还是设计的?所谓设计,我指的是由 @action 假设正在处理在中定义的相同模型 ModelViewSet (在这种情况下是用户,而不是个人资料)?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/131534
文章 [ 1 ]  |  最新文章 4 年前
LiquidDeath
Reply   •   1 楼
LiquidDeath    4 年前

问题在于设置 http_method_names 属性设置为ModelViewSet。既然你把它设为 get post ,其他方法( put , patch , delete )不会在课堂上工作。要么你必须添加 删去 方法 http_方法_名称 属性或移除整个属性来修复此问题,如下所示。

class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer
    queryset = User.objects.all()

    @action(detail=True, methods=['delete'])
    def delete_profile(self, request, pk=None):
        Profile.objects.get(user=pk).delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

如果你不想要别的方法 收到 , 邮递 , 删去 为什么不使用mixins?

更新: 如果不想让delete方法在主视图集上工作,只需覆盖它,如图所示。

 class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer
    queryset = User.objects.all() 

    @action(detail=True, methods=['delete'])
    def delete_profile(self, request, pk=None):
         ....

    def destroy(self, request, *args, **kwargs):
        return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)