背景
我有一个定义了多个自定义操作的 ModelViewSet。我正在使用我的默认路由器urls.py
注册 URL。现在,我的视图使用默认创建的路由,例如^images/$
, ^images/{pk}/$
.
为了让用户能够使用他们熟悉的资源名称来使用 API,我调整了视图集以接受来自 URL 的多个参数,使用多字段查找混合 https://www.django-rest-framework.org/api-guide/generic-views/#creating-custom-mixins文档中描述的策略允许该模式images/{registry_host}/{repository_name}/{tag_name}
.
我已经创建了get_object
我的视图集中的方法如下:
class ImageViewSet(viewsets.ModelViewSet):
...
def get_object(self):
special_lookup_kwargs = ['registry_host', 'repository_name', 'tag_name']
if all(arg in self.kwargs for arg in special_lookup_kwargs):
# detected the custom URL pattern; return the specified object
return Image.objects.from_special_lookup(**self.kwargs)
else: # must have received pk instead; delegate to superclass
return super().get_object()
我还为此添加了一个新的 URL 路径模式:
urls.py
router = routers.DefaultRouter()
router.register(r'images', views.ImageViewSet)
# register other viewsets
...
urlpatterns = [
...,
path('images/<str:registry_host>/<path:repository_name>/<str:tag_name>', views.ImageViewSet.as_view({'get': 'retrieve',})),
path('', include(router.urls)),
]
Problem
以上所有内容均按预期工作,但是,我还有一些额外的内容actions
在此模型视图集中:
@action(detail=True, methods=['GET'])
def bases(self, request, pk=None):
...
@action(detail=True, methods=['GET'])
def another_action(...):
... # and so on
使用 DRF 注册的默认模式,我可以转到images/{pk}/<action>
(like images/{pk}/bases
) 触发额外的操作方法。但是我不能这样做images/{registry_host}/{repository_name}/{tag_name}/<action>
。这在某种程度上是预料之中的,因为我从未注册过任何此类 URL,并且 DRF 没有合理的方式可以了解这一点。
I'm guessing我可以使用适当的参数手动添加所有这些路径path(...)
但我不确定那会是什么。
urlpatterns = [
...,
path('.../myaction', ???)
]
问题
主要问题是如何为我的 URL 添加操作?
但是,我想避免每次添加新的 URL 时都必须添加新的 URL@action()
已添加到视图中。理想情况下,我希望这些在默认路径下自动注册images/{pk}/<action>
也images/{registry_host}/{repository_name}/{tag_name}/<action>
.
作为次要问题,自动实现这一目标的适当方法是什么?我的guess也许是一个自定义路由器。但是,我不清楚如何为所有额外(详细)操作添加这些附加路由。
使用 django/drf 3.2