Jelajahi Sumber

Fixed #21177 -- Made resolve_url support relative URLs.

This fixes redirecting to relative URLs with django.shortcuts.redirect.
Antoine Catton 11 tahun lalu
induk
melakukan
e3d0790bd0

+ 4 - 0
django/core/urlresolvers.py

@@ -383,6 +383,10 @@ class RegexURLResolver(LocaleRegexProvider):
         text_args = [force_text(v) for v in args]
         text_kwargs = dict((k, force_text(v)) for (k, v) in kwargs.items())
 
+        if isinstance(lookup_view, six.string_types):
+            # Handle relative URLs
+            if any(lookup_view.startswith(path) for path in ('./', '../')):
+                return lookup_view
         try:
             lookup_view = get_callable(lookup_view, True)
         except (ImportError, AttributeError) as e:

+ 3 - 0
docs/releases/1.7.txt

@@ -677,6 +677,9 @@ Requests
 * The new :attr:`HttpRequest.scheme <django.http.HttpRequest.scheme>` attribute
   specifies the scheme of the request (``http`` or ``https`` normally).
 
+* The shortcut :func:`redirect() <django.shortcuts.redirect>` now supports
+  relative URLs.
+
 Tests
 ^^^^^
 

+ 7 - 2
docs/topics/http/shortcuts.txt

@@ -203,10 +203,15 @@ If you want to override the :setting:`TEMPLATE_DIRS` setting, use the
      <django.core.urlresolvers.reverse>` will be used to reverse-resolve the
      name.
 
-   * A URL, which will be used as-is for the redirect location.
+   * An absolute or relative URL, which will be used as-is for the redirect
+     location.
 
    By default issues a temporary redirect; pass ``permanent=True`` to issue a
-   permanent redirect
+   permanent redirect.
+
+   .. versionchanged:: 1.7
+
+       The ability to use relative URLs was added.
 
 Examples
 --------

+ 10 - 0
tests/resolve_url/tests.py

@@ -21,6 +21,16 @@ class ResolveUrlTests(TestCase):
         """
         self.assertEqual('/something/', resolve_url('/something/'))
 
+    def test_relative_path(self):
+        """
+        Tests that passing a relative URL path to ``resolve_url`` will result
+        in the same url.
+        """
+        self.assertEqual('../', resolve_url('../'))
+        self.assertEqual('../relative/', resolve_url('../relative/'))
+        self.assertEqual('./', resolve_url('./'))
+        self.assertEqual('./relative/', resolve_url('./relative/'))
+
     def test_full_url(self):
         """
         Tests that passing a full URL to ``resolve_url`` will result in the