Reverse order to checks in reverse.

Add namespace then fallback to non-namespaced to allow reversing of non-namespaced views from namespaced request
This commit is contained in:
Carlton Gibson 2014-04-07 19:51:37 +02:00
parent b10a5908f8
commit 9be01a6e4d
2 changed files with 26 additions and 13 deletions

View File

@ -2,7 +2,7 @@
Provide reverse functions that return fully qualified URLs
"""
from __future__ import unicode_literals
from django.core.urlresolvers import reverse as django_reverse
from django.core.urlresolvers import reverse as django_reverse, NoReverseMatch
from django.utils.functional import lazy
from django.core.urlresolvers import resolve
from django.http import Http404
@ -18,21 +18,27 @@ def reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra
kwargs = kwargs or {}
kwargs['format'] = format
if request:
try:
namespace = request.resolver_match.namespace
except AttributeError:
try:
viewname_to_try = viewname
if request:
try:
namespace = resolve(request.path).namespace
except Http404:
namespace=None
namespace = request.resolver_match.namespace
except AttributeError:
try:
namespace = resolve(request.path).namespace
except Http404:
namespace=None
if namespace and ':' not in viewname:
viewname = '{namespace}:{viewname}'.format(namespace=namespace,
viewname=viewname)
if namespace and ':' not in viewname:
viewname_to_try = '{namespace}:{viewname}'.format(namespace=namespace,
viewname=viewname)
url = django_reverse(viewname_to_try, args=args, kwargs=kwargs,
**extra)
except NoReverseMatch:
url = django_reverse(viewname, args=args, kwargs=kwargs,
**extra)
url = django_reverse(viewname, args=args, kwargs=kwargs,
**extra)
if request:
return request.build_absolute_uri(url)

View File

@ -13,6 +13,7 @@ def null_view(request):
v0_urlpatterns = patterns('',
url(r'^view$', null_view, name='view'),
url(r'^other-view', null_view, name="other-view"),
)
v1_urlpatterns = patterns('',
@ -52,6 +53,12 @@ class ReverseTests(TestCase):
url = reverse('view', request=request)
self.assertEqual(url, 'http://testserver/v2/view')
def test_namespaced_request_to_non_namespaced_view_not_in_namespace(self):
request = factory.get('/v2/view')
url = reverse('other-view', request=request)
self.assertEqual(url, 'http://testserver/other-view')
# Additional tests for #1143
# Covering cases mentioned
# https://github.com/tomchristie/django-rest-framework/pull/1143#issuecomment-30031591