Kaydet (Commit) 7d81ee6e authored tarafından Claude Paroz's avatar Claude Paroz

Fixed #16734 -- Set script prefix even outside of requests

Thanks Tim Graham for the review.
üst 9dcfecb7
from __future__ import unicode_literals
from django.utils.version import get_version from django.utils.version import get_version
VERSION = (1, 10, 0, 'alpha', 0) VERSION = (1, 10, 0, 'alpha', 0)
...@@ -5,14 +7,21 @@ VERSION = (1, 10, 0, 'alpha', 0) ...@@ -5,14 +7,21 @@ VERSION = (1, 10, 0, 'alpha', 0)
__version__ = get_version(VERSION) __version__ = get_version(VERSION)
def setup(): def setup(set_prefix=True):
""" """
Configure the settings (this happens as a side effect of accessing the Configure the settings (this happens as a side effect of accessing the
first setting), configure logging and populate the app registry. 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.apps import apps
from django.conf import settings 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 from django.utils.log import configure_logging
configure_logging(settings.LOGGING_CONFIG, settings.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) apps.populate(settings.INSTALLED_APPS)
...@@ -10,5 +10,5 @@ def get_wsgi_application(): ...@@ -10,5 +10,5 @@ def get_wsgi_application():
Allows us to avoid making django.core.handlers.WSGIHandler public API, in Allows us to avoid making django.core.handlers.WSGIHandler public API, in
case the internal WSGI implementation changes or moves in the future. case the internal WSGI implementation changes or moves in the future.
""" """
django.setup() django.setup(set_prefix=False)
return WSGIHandler() return WSGIHandler()
...@@ -332,14 +332,20 @@ application registry. ...@@ -332,14 +332,20 @@ application registry.
.. currentmodule:: django .. currentmodule:: django
.. function:: setup() .. function:: setup(set_script=True)
Configures Django by: Configures Django by:
* Loading the settings. * Loading the settings.
* Setting up logging. * 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. * Initializing the application registry.
.. versionchanged:: 1.10
The ability to set the URL resolver script prefix is new.
This function is called automatically: This function is called automatically:
* When running an HTTP server via Django's WSGI support. * When running an HTTP server via Django's WSGI support.
......
...@@ -1408,7 +1408,14 @@ Default: ``None`` ...@@ -1408,7 +1408,14 @@ Default: ``None``
If not ``None``, this will be used as the value of the ``SCRIPT_NAME`` 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 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 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 .. setting:: FORMAT_MODULE_PATH
......
...@@ -209,7 +209,10 @@ Tests ...@@ -209,7 +209,10 @@ Tests
URLs 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 Validators
^^^^^^^^^^ ^^^^^^^^^^
......
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')
import os import os
from admin_scripts.tests import AdminScriptTestCase
from django.apps import apps from django.apps import apps
from django.core import management from django.core import management
from django.core.management import BaseCommand, CommandError, find_commands from django.core.management import BaseCommand, CommandError, find_commands
...@@ -159,6 +161,23 @@ class CommandTests(SimpleTestCase): ...@@ -159,6 +161,23 @@ class CommandTests(SimpleTestCase):
BaseCommand.check = saved_check 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): class UtilsTests(SimpleTestCase):
def test_no_existent_external_program(self): def test_no_existent_external_program(self):
......
from django.conf.urls import url
urlpatterns = [
url(r'^some/url/$', lambda req:req, name='some_url'),
]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment