mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-03 12:00:12 +03:00
Add default app namespace to drf reverse
This commit is contained in:
parent
4fbe3ecce6
commit
ec7f358010
|
@ -34,10 +34,29 @@ def preserve_builtin_query_params(url, request=None):
|
||||||
|
|
||||||
def reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra):
|
def reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra):
|
||||||
"""
|
"""
|
||||||
|
Extends `django.urls.reverse` with behavior specific to rest framework.
|
||||||
|
|
||||||
|
The `viewname` will be prepended with the 'rest_framework' application
|
||||||
|
namespace if no namspace is included in the `viewname` argument. The
|
||||||
|
framework fundamentally assumes that the router urls will be included with
|
||||||
|
the 'rest_framework' namespace, so ensure that your root url patterns are
|
||||||
|
configured accordingly. Assuming you use the default router, you can check
|
||||||
|
this with:
|
||||||
|
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
reverse('rest_framework:api-root')
|
||||||
|
|
||||||
If versioning is being used then we pass any `reverse` calls through
|
If versioning is being used then we pass any `reverse` calls through
|
||||||
to the versioning scheme instance, so that the resulting URL
|
to the versioning scheme instance, so that the resulting URL
|
||||||
can be modified if needed.
|
can be modified if needed.
|
||||||
|
|
||||||
|
Optionally takes a `request` object (see `_reverse` for details).
|
||||||
"""
|
"""
|
||||||
|
# prepend the 'rest_framework' application namespace
|
||||||
|
if ':' not in viewname:
|
||||||
|
viewname = 'rest_framework:' + viewname
|
||||||
|
|
||||||
scheme = getattr(request, 'versioning_scheme', None)
|
scheme = getattr(request, 'versioning_scheme', None)
|
||||||
if scheme is not None:
|
if scheme is not None:
|
||||||
try:
|
try:
|
||||||
|
@ -56,6 +75,8 @@ def _reverse(viewname, args=None, kwargs=None, request=None, format=None, **extr
|
||||||
"""
|
"""
|
||||||
Same as `django.urls.reverse`, but optionally takes a request
|
Same as `django.urls.reverse`, but optionally takes a request
|
||||||
and returns a fully qualified URL, using the request to get the base URL.
|
and returns a fully qualified URL, using the request to get the base URL.
|
||||||
|
|
||||||
|
Additionally, the request is used to determine the `current_app` instance.
|
||||||
"""
|
"""
|
||||||
if format is not None:
|
if format is not None:
|
||||||
kwargs = kwargs or {}
|
kwargs = kwargs or {}
|
||||||
|
|
|
@ -19,11 +19,16 @@ apppatterns = ([
|
||||||
url(r'^home$', mock_view, name='home'),
|
url(r'^home$', mock_view, name='home'),
|
||||||
], 'app')
|
], 'app')
|
||||||
|
|
||||||
|
apipatterns = ([
|
||||||
|
url(r'^root$', mock_view, name='root'),
|
||||||
|
], 'rest_framework')
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^view$', mock_view, name='view'),
|
url(r'^view$', mock_view, name='view'),
|
||||||
url(r'^app2/', include(apppatterns, namespace='app2')),
|
url(r'^app2/', include(apppatterns, namespace='app2')),
|
||||||
url(r'^app1/', include(apppatterns, namespace='app1')),
|
url(r'^app1/', include(apppatterns, namespace='app1')),
|
||||||
|
url(r'^api/', include(apipatterns)),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,7 +41,7 @@ class MockVersioningScheme(object):
|
||||||
if self.raise_error:
|
if self.raise_error:
|
||||||
raise NoReverseMatch()
|
raise NoReverseMatch()
|
||||||
|
|
||||||
return 'http://scheme-reversed/view'
|
return 'http://scheme-reversed/api/root'
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='tests.test_reverse')
|
@override_settings(ROOT_URLCONF='tests.test_reverse')
|
||||||
|
@ -44,24 +49,33 @@ class ReverseTests(TestCase):
|
||||||
"""
|
"""
|
||||||
Tests for fully qualified URLs when using `reverse`.
|
Tests for fully qualified URLs when using `reverse`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def test_reverse_non_drf_view(self):
|
||||||
|
request = factory.get('/api/root')
|
||||||
|
|
||||||
|
# DRF reverse should not match non-DRF views
|
||||||
|
with self.assertRaises(NoReverseMatch):
|
||||||
|
reverse('view', request=request)
|
||||||
|
|
||||||
def test_reversed_urls_are_fully_qualified(self):
|
def test_reversed_urls_are_fully_qualified(self):
|
||||||
request = factory.get('/view')
|
request = factory.get('/api/root')
|
||||||
url = reverse('view', request=request)
|
|
||||||
assert url == 'http://testserver/view'
|
url = reverse('root', request=request)
|
||||||
|
assert url == 'http://testserver/api/root'
|
||||||
|
|
||||||
def test_reverse_with_versioning_scheme(self):
|
def test_reverse_with_versioning_scheme(self):
|
||||||
request = factory.get('/view')
|
request = factory.get('/api/root')
|
||||||
request.versioning_scheme = MockVersioningScheme()
|
request.versioning_scheme = MockVersioningScheme()
|
||||||
|
|
||||||
url = reverse('view', request=request)
|
url = reverse('root', request=request)
|
||||||
assert url == 'http://scheme-reversed/view'
|
assert url == 'http://scheme-reversed/api/root'
|
||||||
|
|
||||||
def test_reverse_with_versioning_scheme_fallback_to_default_on_error(self):
|
def test_reverse_with_versioning_scheme_fallback_to_default_on_error(self):
|
||||||
request = factory.get('/view')
|
request = factory.get('/api/root')
|
||||||
request.versioning_scheme = MockVersioningScheme(raise_error=True)
|
request.versioning_scheme = MockVersioningScheme(raise_error=True)
|
||||||
|
|
||||||
url = reverse('view', request=request)
|
url = reverse('root', request=request)
|
||||||
assert url == 'http://testserver/view'
|
assert url == 'http://testserver/api/root'
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='tests.test_reverse')
|
@override_settings(ROOT_URLCONF='tests.test_reverse')
|
||||||
|
@ -76,6 +90,10 @@ class NamespaceTests(TestCase):
|
||||||
def request(self, url):
|
def request(self, url):
|
||||||
return self.client.get(url).wsgi_request
|
return self.client.get(url).wsgi_request
|
||||||
|
|
||||||
|
def test_default_namespace(self):
|
||||||
|
url = reverse('root')
|
||||||
|
assert url == '/api/root'
|
||||||
|
|
||||||
def test_application_namespace(self):
|
def test_application_namespace(self):
|
||||||
url = reverse('app:home')
|
url = reverse('app:home')
|
||||||
assert url == '/app1/home'
|
assert url == '/app1/home'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user