gpt4 book ai didi

Django DRF,如何使用 DRF 操作正确注册自定义 URL 模式

转载 作者:行者123 更新时间:2023-12-05 04:47:08 27 4
gpt4 key购买 nike

背景

我有一个定义了多个自定义操作的 ModelViewSet。我在 urls.py 中使用默认路由器注册 URL。现在,我的 View 使用默认创建的路由,如 ^images/$ , ^images/{pk}/$ .

为了让用户使用他们熟悉的资源名称来使用 API,我调整了 View 集以接受来自 URL 的多个参数,使用 MultipleFieldLookupMixin文档中描述的策略允许模式 images/{registry_host}/{repository_name}/{tag_name} .

我创建了 get_object我的 View 集中的方法是这样的:

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 路径模式:

网址.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)),
]

问题

以上都按预期工作,但是,我还有一些额外的 actions在此模型 View 集中:

    @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> (如 images/{pk}/bases )触发额外的操作方法。但是我不能为 images/{registry_host}/{repository_name}/{tag_name}/<action> 这样做.这在某种程度上是意料之中的,因为我从未注册过任何此类 URL,而且 DRF 也没有合理的方式可以知道这一点。

猜测我可以使用适当的参数手动添加所有这些路径到 path(...)但我不确定那会是什么。

urlpatterns = [
...,
path('.../myaction', ???)
]

问题

作为一个主要问题,我如何为我的 URL 添加操作?

但是,我想避免在每次新的 @action() 时都必须添加新的 URLS。被添加到 View 中。理想情况下,我希望这些在默认路径下自动注册 images/{pk}/<action>以及images/{registry_host}/{repository_name}/{tag_name}/<action> .

作为次要问题,自动实现此目的的合适方法是什么?我猜测可能是一个自定义路由器。但是,我不清楚如何为所有额外(详细)操作添加这些额外的路由。

使用 django/drf 3.2

最佳答案

我看到的另一种方法是(滥用)使用 url_path 和 kwargs,例如:

class ImageViewSet(viewsets.ModelViewSet):

@action(detail=False, methods=['GET'], url_path='<str:registry_host>/<path:repository_name>)/<str:tag_name>/bases')
def bases_special_lookup(...):
# detail=False to remove <pk>

@action(detail=True, methods=['GET'])
def bases(...):
...

@action(detail=False, methods=['GET'], url_path='<str:registry_host>/<path:repository_name>)/<str:tag_name>')
def retrieve_special_lookup(...):
# detail=False to remove <pk>

def retrieve(...):
...

这将创建这些 url:

images/<str:registry_host>/<path:repository_name>/<str:tag_name>/bases
images/<pk>/bases
images/<str:registry_host>/<path:repository_name>/<str:tag_name>
images/<pk>

关于Django DRF,如何使用 DRF 操作正确注册自定义 URL 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68568523/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com