Skip to content

Commit 9c9525b

Browse files
authored
Merge pull request #5187 from mathpresso-mom/list_route_regex
Fix list_route, detail_route with kwargs contains curly bracket in url_path
2 parents 5267fcc + 0ad017a commit 9c9525b

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

rest_framework/routers.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@
3535
DynamicListRoute = namedtuple('DynamicListRoute', ['url', 'name', 'initkwargs'])
3636

3737

38+
def escape_curly_brackets(url_path):
39+
"""
40+
Double brackets in regex of url_path for escape string formatting
41+
"""
42+
if ('{' and '}') in url_path:
43+
url_path = url_path.replace('{', '{{').replace('}', '}}')
44+
return url_path
45+
46+
3847
def replace_methodname(format_string, methodname):
3948
"""
4049
Partially format a format_string, swapping out any
@@ -178,6 +187,7 @@ def _get_dynamic_routes(route, dynamic_routes):
178187
initkwargs = route.initkwargs.copy()
179188
initkwargs.update(method_kwargs)
180189
url_path = initkwargs.pop("url_path", None) or methodname
190+
url_path = escape_curly_brackets(url_path)
181191
url_name = initkwargs.pop("url_name", None) or url_path
182192
ret.append(Route(
183193
url=replace_methodname(route.url, url_path),

tests/test_routers.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ def get_object(self, *args, **kwargs):
6565
return self.queryset[index]
6666

6767

68+
class RegexUrlPathViewSet(viewsets.ViewSet):
69+
@list_route(url_path='list/(?P<kwarg>[0-9]{4})')
70+
def regex_url_path_list(self, request, *args, **kwargs):
71+
kwarg = self.kwargs.get('kwarg', '')
72+
return Response({'kwarg': kwarg})
73+
74+
@detail_route(url_path='detail/(?P<kwarg>[0-9]{4})')
75+
def regex_url_path_detail(self, request, *args, **kwargs):
76+
pk = self.kwargs.get('pk', '')
77+
kwarg = self.kwargs.get('kwarg', '')
78+
return Response({'pk': pk, 'kwarg': kwarg})
79+
80+
6881
notes_router = SimpleRouter()
6982
notes_router.register(r'notes', NoteViewSet)
7083

@@ -80,13 +93,17 @@ def get_object(self, *args, **kwargs):
8093
url(r'^', include(empty_prefix_router.urls)),
8194
]
8295

96+
regex_url_path_router = SimpleRouter()
97+
regex_url_path_router.register(r'', RegexUrlPathViewSet, base_name='regex')
98+
8399
urlpatterns = [
84100
url(r'^non-namespaced/', include(namespaced_router.urls)),
85101
url(r'^namespaced/', include(namespaced_router.urls, namespace='example', app_name='example')),
86102
url(r'^example/', include(notes_router.urls)),
87103
url(r'^example2/', include(kwarged_notes_router.urls)),
88104

89105
url(r'^empty-prefix/', include(empty_prefix_urls)),
106+
url(r'^regex/', include(regex_url_path_router.urls))
90107
]
91108

92109

@@ -402,3 +419,19 @@ def test_empty_prefix_detail(self):
402419
response = self.client.get('/empty-prefix/1/')
403420
assert response.status_code == 200
404421
assert json.loads(response.content.decode('utf-8')) == {'uuid': '111', 'text': 'First'}
422+
423+
424+
@override_settings(ROOT_URLCONF='tests.test_routers')
425+
class TestRegexUrlPath(TestCase):
426+
def test_regex_url_path_list(self):
427+
kwarg = '1234'
428+
response = self.client.get('/regex/list/{}/'.format(kwarg))
429+
assert response.status_code == 200
430+
assert json.loads(response.content.decode('utf-8')) == {'kwarg': kwarg}
431+
432+
def test_regex_url_path_detail(self):
433+
pk = '1'
434+
kwarg = '1234'
435+
response = self.client.get('/regex/{}/detail/{}/'.format(pk, kwarg))
436+
assert response.status_code == 200
437+
assert json.loads(response.content.decode('utf-8')) == {'pk': pk, 'kwarg': kwarg}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy