从现有的Drf模型视图集中删除特定操作

时间:2019-12-26 07:31:08

标签: python django django-rest-framework

我重新使用了现有的drf模型视图集,但是我不需要一些自定义动作(用@action标签分配)。如何在不修改原始模型视图集的情况下从django rest框架中隐藏/删除它?

例如

class MyViewSet(viewsets.ModelViewSet):
    @action(["get",], detail=False)
    def custom_a(self, request):
        # some stuff

    @action(["get",], detail=False)
    def custom_b(self, request):
        # some stuff

    @action(["get",], detail=False)
    def custom_c(self, request):
        # some stuff

我的路由器

router = routers.SimpleRouter()
router.register("dummies", views.MyViewSet)


urlpatterns = [
    path('', include(router.urls)),
]

然后我将拥有这些端点

GET /dummies/
GET /dummies/{id}/
POST /dummies/
PUT /dummies/{id}/
PATCH /dummies/{id}/
DELETE /dummies/{id}/
GET /dummies/custom_a/
GET /dummies/custom_b/
GET /dummies/custom_c/

现在我该如何保留 5个第一视图获取/ dummies / custom_a /

谢谢。

1 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点,但是“最干净的”似乎是最重要的。

覆盖并忽略

装饰器不是“继承”的,因此您可以在派生类上重新声明该方法。此新方法优先于基类方法,因此DRF不再将它们视为@action

class View1(viewsets.ModelViewSet):
    @action(['get'], detail=False)
    def act_up(self, request):
        pass

    class Meta:
        model = Client
        fields = "__all__"

class View2(View1):

    # redefine and don't add the @action decorator
    def act_up(self, request):
        pass

    class Meta:  
        model = View1.Meta.model
        fields = View1.Meta.fields

使用路由器,并删除了不需要的方法

路由器URL仅计算一次然后缓存。您可以做到这一点,然后过滤掉不需要的(按名称)

router = SimpleRouter()
router.register("view1", View1, basename="v1")
router._urls = [
    r for r in router.urls
    if not any(r.name.endswith(bad) for bad in ['-act-up', '-other-rt']
]

手动路由到动作

您可以manually create the routes,与基本SimpleRouter一样。这还有很多工作,而且最不值得的

list_paths = View1.as_view({"get": "list"})
detail_paths = View1.as_view({"get": "retrieve", "patch": "partial_update"})
urlpatterns = [
    path("view1/", list_paths, name="view1-list"),
    path("view1/<int:pk>/", detail_paths, name="view1-detail")
]

这是将url + http method(例如get)绑定到特定的DRF“操作”(列表/检索/销毁等)。因此,GET view11/action=list调用您的视图集,然后该视图集在内部将其分派到正确的方法。

由于仅映射所需的内容,因此无法调用那些不好的“其他”方法。

这有点棘手,令人困惑,并且使您对路由负责,一起使维护和理解工作变得更加艰巨。如果没有其他方法,或者只需要ViewSet中的1个或2个方法,则可以使用OK选项。