mirror of https://github.com/django/django.git
Fixed #5925 -- Added new lazily evaluated version of django.core.urlresolvers.reverse. Thanks, SmileyChris, Preston Timmons and Julien Phalip.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16121 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
f459169170
commit
79afd55278
|
@ -15,7 +15,7 @@ from django.conf import settings
|
|||
from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
|
||||
from django.utils.datastructures import MultiValueDict
|
||||
from django.utils.encoding import iri_to_uri, force_unicode, smart_str
|
||||
from django.utils.functional import memoize
|
||||
from django.utils.functional import memoize, lazy
|
||||
from django.utils.importlib import import_module
|
||||
from django.utils.regex_helper import normalize
|
||||
|
||||
|
@ -390,6 +390,8 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, current
|
|||
return iri_to_uri(u'%s%s' % (prefix, resolver.reverse(view,
|
||||
*args, **kwargs)))
|
||||
|
||||
reverse_lazy = lazy(reverse, str)
|
||||
|
||||
def clear_url_caches():
|
||||
global _resolver_cache
|
||||
global _callable_cache
|
||||
|
|
|
@ -37,6 +37,12 @@ compatibility with old browsers, this change means that you can use any HTML5
|
|||
features you need in admin pages without having to lose HTML validity or
|
||||
override the provided templates to change the doctype.
|
||||
|
||||
``reverse_lazy``
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
A lazily evaluated version of :func:`django.core.urlresolvers.reverse` was
|
||||
added to allow using URL reversals before the project's URLConf gets loaded.
|
||||
|
||||
.. _backwards-incompatible-changes-1.4:
|
||||
|
||||
Backwards incompatible changes in 1.4
|
||||
|
|
|
@ -827,6 +827,26 @@ namespaces into URLs on specific application instances, according to the
|
|||
``urllib.quote``) to the ouput of :meth:`~django.core.urlresolvers.reverse`
|
||||
may produce undesirable results.
|
||||
|
||||
reverse_lazy()
|
||||
--------------
|
||||
|
||||
.. versionadded:: 1.4
|
||||
|
||||
A lazily evaluated version of `reverse()`_.
|
||||
|
||||
It is useful for when you need to use a URL reversal before your project's
|
||||
URLConf is loaded. Some common cases where this method is necessary are::
|
||||
|
||||
* providing a reversed URL as the ``url`` attribute of a generic class-based
|
||||
view.
|
||||
|
||||
* providing a reversed URL to a decorator (such as the ``login_url`` argument
|
||||
for the :func:`django.contrib.auth.decorators.permission_required`
|
||||
decorator).
|
||||
|
||||
* providing a reversed URL as a default value for a parameter in a function's
|
||||
signature.
|
||||
|
||||
resolve()
|
||||
---------
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
|
|||
from django.shortcuts import redirect
|
||||
from django.test import TestCase
|
||||
from django.utils import unittest
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
import urlconf_outer
|
||||
import urlconf_inner
|
||||
|
@ -218,6 +219,21 @@ class ResolverTests(unittest.TestCase):
|
|||
else:
|
||||
self.assertEqual(t.name, e['name'], 'Wrong URL name. Expected "%s", got "%s".' % (e['name'], t.name))
|
||||
|
||||
class ReverseLazyTest(TestCase):
|
||||
urls = 'regressiontests.urlpatterns_reverse.reverse_lazy_urls'
|
||||
|
||||
def test_redirect_with_lazy_reverse(self):
|
||||
response = self.client.get('/redirect/')
|
||||
self.assertRedirects(response, "/redirected_to/", status_code=301)
|
||||
|
||||
def test_user_permission_with_lazy_reverse(self):
|
||||
user = User.objects.create_user('alfred', 'alfred@example.com', password='testpw')
|
||||
response = self.client.get('/login_required_view/')
|
||||
self.assertRedirects(response, "/login/?next=/login_required_view/", status_code=302)
|
||||
self.client.login(username='alfred', password='testpw')
|
||||
response = self.client.get('/login_required_view/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
class ReverseShortcutTests(TestCase):
|
||||
urls = 'regressiontests.urlpatterns_reverse.urls'
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
from django.http import HttpResponse
|
||||
from django.views.generic import RedirectView
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
|
||||
from django.contrib.auth.decorators import user_passes_test
|
||||
|
||||
def empty_view(request, *args, **kwargs):
|
||||
return HttpResponse('')
|
||||
|
@ -15,5 +19,12 @@ class ViewClass(object):
|
|||
|
||||
view_class_instance = ViewClass()
|
||||
|
||||
class LazyRedictView(RedirectView):
|
||||
url = reverse_lazy('named-lazy-url-redirected-to')
|
||||
|
||||
@user_passes_test(lambda u: u.is_authenticated(), login_url=reverse_lazy('some-login-page'))
|
||||
def login_required_view(request):
|
||||
return HttpResponse('Hello you')
|
||||
|
||||
def bad_view(request, *args, **kwargs):
|
||||
raise ValueError("I don't think I'm getting good value for this view")
|
||||
|
|
Loading…
Reference in New Issue