summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2015-10-23 21:02:34 +0200
committerClaude Paroz <claude@2xlibre.net>2015-10-29 20:12:38 +0100
commit7d81ee6efc385f7d4c1218639e4102c64495ba0f (patch)
tree1ad9200f0775f223cff67b770dbda1f929e516d3
parent9dcfecb7c6c8285630ad271888a9ec4ba9140e3a (diff)
downloaddjango-7d81ee6efc385f7d4c1218639e4102c64495ba0f.tar.gz
Fixed #16734 -- Set script prefix even outside of requests
Thanks Tim Graham for the review.
-rw-r--r--django/__init__.py11
-rw-r--r--django/core/wsgi.py2
-rw-r--r--docs/ref/applications.txt8
-rw-r--r--docs/ref/settings.txt9
-rw-r--r--docs/releases/1.10.txt5
-rw-r--r--tests/user_commands/management/commands/reverse_url.py10
-rw-r--r--tests/user_commands/tests.py19
-rw-r--r--tests/user_commands/urls.py5
8 files changed, 64 insertions, 5 deletions
diff --git a/django/__init__.py b/django/__init__.py
index 3025f721bd..c9c3ecf17a 100644
--- a/django/__init__.py
+++ b/django/__init__.py
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
from django.utils.version import get_version
VERSION = (1, 10, 0, 'alpha', 0)
@@ -5,14 +7,21 @@ VERSION = (1, 10, 0, 'alpha', 0)
__version__ = get_version(VERSION)
-def setup():
+def setup(set_prefix=True):
"""
Configure the settings (this happens as a side effect of accessing the
first setting), configure logging and populate the app registry.
+ Set the thread-local urlresolvers script prefix if `set_prefix` is True.
"""
from django.apps import apps
from django.conf import settings
+ from django.core.urlresolvers import set_script_prefix
+ from django.utils.encoding import force_text
from django.utils.log import configure_logging
configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
+ if set_prefix:
+ set_script_prefix(
+ '/' if settings.FORCE_SCRIPT_NAME is None else force_text(settings.FORCE_SCRIPT_NAME)
+ )
apps.populate(settings.INSTALLED_APPS)
diff --git a/django/core/wsgi.py b/django/core/wsgi.py
index 62aa43bda5..e0ded3db54 100644
--- a/django/core/wsgi.py
+++ b/django/core/wsgi.py
@@ -10,5 +10,5 @@ def get_wsgi_application():
Allows us to avoid making django.core.handlers.WSGIHandler public API, in
case the internal WSGI implementation changes or moves in the future.
"""
- django.setup()
+ django.setup(set_prefix=False)
return WSGIHandler()
diff --git a/docs/ref/applications.txt b/docs/ref/applications.txt
index 498e10c954..ba0ddeb532 100644
--- a/docs/ref/applications.txt
+++ b/docs/ref/applications.txt
@@ -332,14 +332,20 @@ application registry.
.. currentmodule:: django
-.. function:: setup()
+.. function:: setup(set_script=True)
Configures Django by:
* Loading the settings.
* Setting up logging.
+ * If ``set_script`` is True, setting the URL resolver script prefix to
+ :setting:`FORCE_SCRIPT_NAME` if defined, or ``/`` otherwise.
* Initializing the application registry.
+ .. versionchanged:: 1.10
+
+ The ability to set the URL resolver script prefix is new.
+
This function is called automatically:
* When running an HTTP server via Django's WSGI support.
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index dba54e26b4..705cecbb57 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -1408,7 +1408,14 @@ Default: ``None``
If not ``None``, this will be used as the value of the ``SCRIPT_NAME``
environment variable in any HTTP request. This setting can be used to override
the server-provided value of ``SCRIPT_NAME``, which may be a rewritten version
-of the preferred value or not supplied at all.
+of the preferred value or not supplied at all. It is also used by
+:func:`django.setup()` to set the URL resolver script prefix outside of the
+request/response cycle (e.g. in management commands and standalone scripts) to
+generate correct URLs when ``SCRIPT_NAME`` is not ``/``.
+
+.. versionchanged:: 1.10
+
+ The setting's use in :func:`django.setup()` was added.
.. setting:: FORMAT_MODULE_PATH
diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt
index b291dcfd41..bea1dc10d1 100644
--- a/docs/releases/1.10.txt
+++ b/docs/releases/1.10.txt
@@ -209,7 +209,10 @@ Tests
URLs
^^^^
-* ...
+* An addition in :func:`django.setup()` allows URL resolving that happens
+ outside of the request/response cycle (e.g. in management commands and
+ standalone scripts) to take :setting:`FORCE_SCRIPT_NAME` into account when it
+ is set.
Validators
^^^^^^^^^^
diff --git a/tests/user_commands/management/commands/reverse_url.py b/tests/user_commands/management/commands/reverse_url.py
new file mode 100644
index 0000000000..f2064bf05d
--- /dev/null
+++ b/tests/user_commands/management/commands/reverse_url.py
@@ -0,0 +1,10 @@
+from django.core.management.base import BaseCommand
+from django.core.urlresolvers import reverse
+
+
+class Command(BaseCommand):
+ """
+ This command returns a URL from a reverse() call.
+ """
+ def handle(self, *args, **options):
+ return reverse('some_url')
diff --git a/tests/user_commands/tests.py b/tests/user_commands/tests.py
index 772da22bed..048ac4d963 100644
--- a/tests/user_commands/tests.py
+++ b/tests/user_commands/tests.py
@@ -1,5 +1,7 @@
import os
+from admin_scripts.tests import AdminScriptTestCase
+
from django.apps import apps
from django.core import management
from django.core.management import BaseCommand, CommandError, find_commands
@@ -159,6 +161,23 @@ class CommandTests(SimpleTestCase):
BaseCommand.check = saved_check
+class CommandRunTests(AdminScriptTestCase):
+ """
+ Tests that need to run by simulating the command line, not by call_command.
+ """
+ def tearDown(self):
+ self.remove_settings('settings.py')
+
+ def test_script_prefix_set_in_commands(self):
+ self.write_settings('settings.py', apps=['user_commands'], sdict={
+ 'ROOT_URLCONF': '"user_commands.urls"',
+ 'FORCE_SCRIPT_NAME': '"/PREFIX/"',
+ })
+ out, err = self.run_manage(['reverse_url'])
+ self.assertNoOutput(err)
+ self.assertEqual(out.strip(), '/PREFIX/some/url/')
+
+
class UtilsTests(SimpleTestCase):
def test_no_existent_external_program(self):
diff --git a/tests/user_commands/urls.py b/tests/user_commands/urls.py
new file mode 100644
index 0000000000..fe20693dce
--- /dev/null
+++ b/tests/user_commands/urls.py
@@ -0,0 +1,5 @@
+from django.conf.urls import url
+
+urlpatterns = [
+ url(r'^some/url/$', lambda req:req, name='some_url'),
+]