python - 使用自定义 url_path 在 @list_route 上反转

标签 python django django-rest-framework

如果我有一个包含以下代码的 View 集:

class ExtraRouteViewset(viewsets.GenericViewSet):
    @list_route(methods=['get'])
    def somefunction(self, request):
        return Response({
            'key': 'value',
            'reverse': reverse('extraroute-somefunction'),
        })

    @list_route(methods=['get'], url_path='arguments/(?P<thing>[^/]+)')
    def arguments(self, request, thing):
        return Response({
            'key': thing,
            'reverse': reverse('extraroute-arguments', kwargs={'thing': 'something'}),
        })

我希望这两种方法都能奏效。然而,第二个 reverse提出 NoReverseMatch .检查 url 模式(通过导航到一个不存在的 url)显示以下 url 模式:

^demo/ ^ ^extraroute/arguments/(?P<thing>[^/]+)/$ [name='extraroute-arguments/(?P<thing>[^/]+)']
^demo/ ^ ^extraroute/arguments/(?P<thing>[^/]+)/\.(?P<format>[a-z0-9]+)$ [name='extraroute-arguments/(?P<thing>[^/]+)']
^demo/ ^ ^extraroute/somefunction/$ [name='extraroute-somefunction']
^demo/ ^ ^extraroute/somefunction/\.(?P<format>[a-z0-9]+)$ [name='extraroute-somefunction']

View 名称似乎是extraroute-arguments/(?P<thing>[^/]+)而不是 extraroute-arguments ?事实上,如果我使用 reverse('extraroute-arguments/(?P<thing>[^/]+)', kwargs={'thing': 'something'})有用。我在这里遗漏了一些非常明显的东西吗,或者这是 django-rest-framework 中的错误? ?

这是使用 Django 1.8a 和 django-rest-framework 3.0.5。

最佳答案

那么,在第二个示例中,您发送 url_path='arguments/(?P<thing>[^/]+)' . Django REST 框架 use it创建一个 URL pattern和一个 URL Name .但是the implementation太纯粹了,无法去除正则表达式。

使用自定义路由器的解决方案

#inside urls.py
router = SimpleRouter()
router.routes.append(
    Route(
        url=r'^{prefix}/arguments/(?P<thing>[^/]+)$',
        name='{basename}-arguments',
        mapping={
            'get': 'arguments',
        },
        initkwargs={}
    ),
)
router.register('extraroute', ExtraRouteViewset, base_name='extraroute')
urlpatterns = router.urls

然后在 views.py 中删除 @list_route装饰器,因为它不再需要(并且会导致路由冲突)

#inside views.py
class ExtraRouteViewset(viewsets.GenericViewSet):
    #...

    def arguments(self, request, thing):
        return Response({
            'key': thing,
            'reverse': reverse('extraroute-arguments', kwargs={'thing': 'something'}),
        })

我不得不提一下,这实际上添加了一个硬编码的 Route模式里面默认SimpleRouter (具有列表、创建、检索、更新、部分更新、销毁的模式)。这意味着通过该路由器实例注册的每个 View 集将能够实现arguments。方法,当正则表达式匹配时将调用此方法。

关于python - 使用自定义 url_path 在 @list_route 上反转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28841600/

相关文章:

Python opencv 没有收到相机提要

python - 使用 Lighttpd 和 CGI​​ 执行 Python 脚本

django - 在 Django 中的选择字段上组合查询集

jquery - 表单提交前预览图像

python - 如何在 Python 中获取指向原始二进制数据的指针?

python - 在哪里可以找到 python 解释器错误代码?

python - 提交按钮在 django 中不起作用

python - DRF ModelMultipleChoiceFilter - 许多参数之一中的无效值导致空列表

django-models - Django rest框架详细获取验证错误对象

python - Django 休息框架 : How do I order/sort a search/filter query?