我重新使用了现有的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 / ?
谢谢。
答案 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选项。