使用自定义url_path在@list_route上反转 [英] reverse on @list_route with custom url_path

查看:114
本文介绍了使用自定义url_path在@list_route上反转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

If I have a viewset with the following code:

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'}),
        })

I希望这两种方法都能奏效。但是,第二个 reverse 会引发 NoReverseMatch 。检查网址格式(通过导航到一个不存在的网址)将显示以下网址格式:

I would expect both methods to work. However, the second reverse raises a NoReverseMatch. Examining the url patterns (by navigating to a non-existing url) shows the following url patterns:

^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']

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

The view name seems to be extraroute-arguments/(?P<thing>[^/]+) instead of extraroute-arguments? And indeed, if I use reverse('extraroute-arguments/(?P<thing>[^/]+)', kwargs={'thing': 'something'}) it works. Am I missing something very obvious here, or is this a bug in django-rest-framework?

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

This is using Django 1.8a and django-rest-framework 3.0.5.

推荐答案

好,在第二个示例中,您发送 url_path ='arguments /(?P< thing> [^ /] +)'。 Django REST框架使用它创建 URL模式 URL名称两者。但是实现太纯净了,无法实现

Well, in the second example, you send url_path='arguments/(?P<thing>[^/]+)'. Django REST framework use it to create both an URL pattern and a URL Name. But the implementation is too pure to strip the regex expression.

#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 装饰器,因为它不再需要(这将导致路线冲突)

and then in the views.py remove the @list_route decorators since its no more needed (and will cause a route clash)

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

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

我不得不提到,这实际上增加了一个硬编码的<$默认 SimpleRouter 中的c $ c> Route 模式(具有用于列表,创建,检索,更新,部分更新,销毁的模式)。这意味着通过此路由器实例注册的每个视图集将能够实现 arguments 方法,并且当正则表达式匹配时将调用此方法

I have to mention that this actually adds a hardcoded Route pattern inside the default SimpleRouter (which has patterns for list, create, retrieve, update, partial update, destroy). This means that every viewset which get registered via this router instance will be able to implement an arguments method and this method will be called when the regex match it.

这篇关于使用自定义url_path在@list_route上反转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆