Skip to content

Commit 1d0553d

Browse files
authored
Merge pull request #355 from Gibsondz/master
- Support For DRF 3.15 nested SimpleRouter.use_regex_path = False - CI is back to test over DRF 3.14, that still works. - CI is no more tested over Python 3.8, that is EOL right now.
2 parents 1fc4efb + 25aa065 commit 1d0553d

File tree

6 files changed

+45
-7
lines changed

6 files changed

+45
-7
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ exist without a domain, so you need it "nested" inside the domain.
1717

1818
## Requirements & Compatibility
1919

20-
- Python (3.8, 3.9, 3.10, 3.11, 3.12, 3.13)
20+
- Python (3.9, 3.10, 3.11, 3.12, 3.13)
2121
- Django (4.2, 5.0, 5.1)
2222
- Django REST Framework (3.14, 3.15)
2323

24-
It may work with lower versions, but since the release **0.93.5** is no more tested on CI for Python 3.6 or lower.<br/>
24+
It may work with lower versions, but since the release **0.94.2** is no more tested on CI for Python 3.8 or lower.<br/>
2525
And since **0.92.1** is no more tested on CI for Pythons 2.7 to 3.5, Django 1.11 to 2.1 or DRF 3.6 to 3.10.<br/>
2626
Before that, the release **0.90.2** was tested also with DRF 2.4.3 up to 3.7.
2727

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33

44
# Minimum Django and REST framework version
55
Django>=4.2
6-
djangorestframework>=3.14.0
6+
djangorestframework>=3.15.0
77

rest_framework_nested/routers.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def __init__(
5959
self.parent_prefix = parent_prefix
6060
self.nest_count = getattr(parent_router, 'nest_count', 0) + 1
6161
self.nest_prefix = kwargs.pop('lookup', f'nested_{self.nest_count}') + '_'
62+
self.use_regex_path = kwargs.get('use_regex_path', True)
6263

6364
super().__init__(*args, **kwargs)
6465

@@ -111,7 +112,11 @@ def __init__(
111112
# to escape it
112113
escaped_parent_regex = self.parent_regex.replace('{', '{{').replace('}', '}}')
113114

114-
route_contents['url'] = route.url.replace('^', '^' + escaped_parent_regex)
115+
if self.use_regex_path:
116+
route_contents['url'] = route.url.replace('^', '^' + escaped_parent_regex)
117+
else:
118+
route_contents['url'] = escaped_parent_regex + route_contents['url']
119+
115120
nested_routes.append(type(route)(**route_contents))
116121

117122
self.routes = nested_routes

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def get_package_data(package):
7676
packages=get_packages(package),
7777
package_data=get_package_data(package),
7878
install_requires=[
79-
'djangorestframework>=3.14.0',
79+
'djangorestframework>=3.15.0',
8080
'Django>=4.2',
8181
],
8282
python_requires=">=3.8",

tests/test_routers.py

+34
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ class AViewSet(ModelViewSet):
5151
queryset = QS(A)
5252

5353

54+
class ANonRegexViewSet(ModelViewSet):
55+
model = A
56+
queryset = QS(A)
57+
58+
5459
class BViewSet(ModelViewSet):
5560
model = B
5661
queryset = QS(B)
@@ -90,6 +95,35 @@ def test_recursive_nested_simple_routers(self):
9095
self.assertEqual(get_regex_pattern(urls[1]), '^a/(?P<a_pk>[0-9a-f]{32})/b/(?P<b_pk>[^/.]+)/c/(?P<pk>[^/.]+)/$')
9196

9297

98+
class TestNonRegexNestedSimpleRouter(TestCase):
99+
def setUp(self):
100+
self.router = SimpleRouter(use_regex_path=False)
101+
self.router.register(r'a', ANonRegexViewSet)
102+
self.a_router = NestedSimpleRouter(self.router, r'a', lookup='a', use_regex_path=False)
103+
self.a_router.register(r'b', BViewSet)
104+
self.b_router = NestedSimpleRouter(self.a_router, r'b', lookup='b', use_regex_path=False)
105+
self.b_router.register(r'c', CViewSet)
106+
107+
def test_non_regex_recursive_nested_simple_routers(self):
108+
self.assertFalse(hasattr(self.router, 'parent_regex'))
109+
urls = self.router.urls
110+
111+
self.assertEqual(pattern_from_url(urls[0]), 'a/')
112+
self.assertEqual(pattern_from_url(urls[1]), 'a/<str:pk>/')
113+
114+
self.assertEqual(self.a_router.parent_regex, 'a/<str:a_pk>/')
115+
urls = self.a_router.urls
116+
self.assertEqual(len(urls), 2)
117+
self.assertEqual(pattern_from_url(urls[0]), 'a/<str:a_pk>/b/')
118+
self.assertEqual(pattern_from_url(urls[1]), 'a/<str:a_pk>/b/<str:pk>/')
119+
120+
self.assertEqual(self.b_router.parent_regex, 'a/<str:a_pk>/b/<str:b_pk>/')
121+
urls = self.b_router.urls
122+
self.assertEqual(len(urls), 2)
123+
self.assertEqual(pattern_from_url(urls[0]), 'a/<str:a_pk>/b/<str:b_pk>/c/')
124+
self.assertEqual(pattern_from_url(urls[1]), 'a/<str:a_pk>/b/<str:b_pk>/c/<str:pk>/')
125+
126+
93127
class TestEmptyPrefix(TestCase):
94128
def setUp(self):
95129
self.router = SimpleRouter()

tox.ini

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
[tox]
22
# see https://docs.djangoproject.com/en/5.1/faq/install/#what-python-version-can-i-use-with-django
33
envlist =
4-
py{38,39,310,311,312}-django4.2-drf{3.14,3.15}
4+
py{39,310,311,312}-django4.2-drf{3.14,3.15}
55
py{310,311,312}-django5.0-drf{3.14,3.15}
66
py{310,311,312,313}-django5.1-drf{3.14,3.15}
77
py312-mypy
88

99
[gh-actions]
1010
python =
11-
3.8: py38
1211
3.9: py39
1312
3.10: py310
1413
3.11: py311

0 commit comments

Comments
 (0)