如何使用 DRF 的
reverse
从 SimpleRouter
调用复杂的 URL?
我的网址有两个地方,一处是团队的,一处是比赛的,如下:
league.urls:
url(r'^team/', include('teams.urls')),
团队.url:
router = SimpleRouter()
router.register(r'game', GameViewSet, 'games')
我正在尝试
reverse
更新游戏的网址。基于 DRF SimpleRouter,这应该是“/team/{pk}/game/{pk}”
我的测试正在呼叫:
url = reverse('games-detail', args=[team.pk, game.pk])
但是我收到以下错误:
raise error, v # invalid expression
error: redefinition of group name u'pk' as group 2; was group 1
YPCrumble,您需要使用不同的
URL
来调用 kwargs
。 URL
正则表达式以处理 kwargs
的方式工作。例如:
# python reverse url
url = reverse('games-detail', kwargs={'team_pk': 1, 'group_pk':1})
# url regex
url(
r'^team/(?P<team_pk>\d+)/group/(?P<group_pk>\d+)/$',
view.SimpleRouterDetailView.as_view(),
name='games-detail'
)
该问题似乎与 URL 模式中命名组的使用有关。在
args
函数中使用 reverse
参数,会导致与 URL 模式中的命名组发生冲突。
为了解决这个问题,我们可以使用
kwargs
函数中的 reverse
参数来传递命名组的值。例子如下:
url = reverse('games-detail', kwargs={'team_pk': team.pk, 'pk': game.pk})
在此示例中,
team_pk
对应于 URL 模式中的命名组 team_pk
,pk
对应于命名组 pk
。
确保您已在 URL 模式中定义了这些命名组。您的
team.urls
可能看起来像这样:
router = SimpleRouter()
router.register(r'game', GameViewSet, 'games')
urlpatterns = [
url(r'^{team_pk}/', include(router.urls)),
]
然后,在你的
league.urls
:
urlpatterns = [
url(r'^team/', include('teams.urls')),
]
通过
kwargs
函数中的 reverse
传递值,您可以避免与 URL 模式中的命名组发生冲突,并确保反向 URL 生成正常工作。
为了更好的理解: