From 5c53e30607014163872e89c221b206992a9acfef Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sun, 8 Apr 2012 21:13:32 +0000 Subject: [PATCH] Fixed #18035 -- Removed deprecated AdminMediaHandler, as per official deprecation timeline. Thanks Jannis Leidel and Ramiro Morales for the review. git-svn-id: http://code.djangoproject.com/svn/django/trunk@17879 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- .../admin/static/admin/js/SelectFilter2.js | 8 +-- django/contrib/gis/admin/widgets.py | 3 +- .../management/commands/runserver.py | 6 +- django/core/management/commands/runserver.py | 17 ++--- django/core/servers/basehttp.py | 50 +------------- docs/howto/deployment/wsgi/gunicorn.txt | 2 +- docs/man/django-admin.1 | 5 +- docs/ref/django-admin.txt | 14 +--- tests/regressiontests/admin_scripts/tests.py | 4 +- tests/regressiontests/admin_widgets/tests.py | 20 +++--- tests/regressiontests/servers/tests.py | 66 +------------------ 11 files changed, 31 insertions(+), 164 deletions(-) diff --git a/django/contrib/admin/static/admin/js/SelectFilter2.js b/django/contrib/admin/static/admin/js/SelectFilter2.js index 0accd080b7..24d88f7cc8 100644 --- a/django/contrib/admin/static/admin/js/SelectFilter2.js +++ b/django/contrib/admin/static/admin/js/SelectFilter2.js @@ -13,7 +13,7 @@ function findForm(node) { } window.SelectFilter = { - init: function(field_id, field_name, is_stacked, admin_media_prefix) { + init: function(field_id, field_name, is_stacked, admin_static_prefix) { if (field_id.match(/__prefix__/)){ // Don't intialize on empty forms. return; @@ -43,14 +43,14 @@ window.SelectFilter = { var selector_available = quickElement('div', selector_div, ''); selector_available.className = 'selector-available'; var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name])); - quickElement('img', title_available, '', 'src', admin_media_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of available %s. You may choose some by selecting them in the box below and then clicking the "Choose" arrow between the two boxes.'), [field_name])); + quickElement('img', title_available, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of available %s. You may choose some by selecting them in the box below and then clicking the "Choose" arrow between the two boxes.'), [field_name])); var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); filter_p.className = 'selector-filter'; var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input"); - var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_media_prefix + 'img/selector-search.gif', 'class', 'help-tooltip', 'alt', '', 'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])); + var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_static_prefix + 'img/selector-search.gif', 'class', 'help-tooltip', 'alt', '', 'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])); filter_p.appendChild(document.createTextNode(' ')); @@ -73,7 +73,7 @@ window.SelectFilter = { var selector_chosen = quickElement('div', selector_div, ''); selector_chosen.className = 'selector-chosen'; var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name])); - quickElement('img', title_chosen, '', 'src', admin_media_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of chosen %s. You may remove some by selecting them in the box below and then clicking the "Remove" arrow between the two boxes.'), [field_name])); + quickElement('img', title_chosen, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of chosen %s. You may remove some by selecting them in the box below and then clicking the "Remove" arrow between the two boxes.'), [field_name])); var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name')); to_box.className = 'filtered'; diff --git a/django/contrib/gis/admin/widgets.py b/django/contrib/gis/admin/widgets.py index 6dbbc60d20..aaffae8f5f 100644 --- a/django/contrib/gis/admin/widgets.py +++ b/django/contrib/gis/admin/widgets.py @@ -8,8 +8,7 @@ from django.contrib.gis.geos import GEOSGeometry, GEOSException # Creating a template context that contains Django settings # values needed by admin map templates. -geo_context = Context({'ADMIN_MEDIA_PREFIX' : static('admin/'), - 'LANGUAGE_BIDI' : translation.get_language_bidi()}) +geo_context = Context({'LANGUAGE_BIDI' : translation.get_language_bidi()}) class OpenLayersWidget(Textarea): """ diff --git a/django/contrib/staticfiles/management/commands/runserver.py b/django/contrib/staticfiles/management/commands/runserver.py index 403df88d81..0f9e39f7c0 100644 --- a/django/contrib/staticfiles/management/commands/runserver.py +++ b/django/contrib/staticfiles/management/commands/runserver.py @@ -1,12 +1,12 @@ from optparse import make_option from django.conf import settings -from django.core.management.commands.runserver import BaseRunserverCommand +from django.core.management.commands.runserver import Command as RunserverCommand from django.contrib.staticfiles.handlers import StaticFilesHandler -class Command(BaseRunserverCommand): - option_list = BaseRunserverCommand.option_list + ( +class Command(RunserverCommand): + option_list = RunserverCommand.option_list + ( make_option('--nostatic', action="store_false", dest='use_static_handler', default=True, help='Tells Django to NOT automatically serve static files at STATIC_URL.'), make_option('--insecure', action="store_true", dest='insecure_serving', default=False, diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py index e93af96286..3007d0fd30 100644 --- a/django/core/management/commands/runserver.py +++ b/django/core/management/commands/runserver.py @@ -5,7 +5,7 @@ import sys import socket from django.core.management.base import BaseCommand, CommandError -from django.core.servers.basehttp import AdminMediaHandler, run, WSGIServerException, get_internal_wsgi_application +from django.core.servers.basehttp import run, WSGIServerException, get_internal_wsgi_application from django.utils import autoreload naiveip_re = re.compile(r"""^(?: @@ -17,7 +17,7 @@ naiveip_re = re.compile(r"""^(?: DEFAULT_PORT = "8000" -class BaseRunserverCommand(BaseCommand): +class Command(BaseCommand): option_list = BaseCommand.option_list + ( make_option('--ipv6', '-6', action='store_true', dest='use_ipv6', default=False, help='Tells Django to use a IPv6 address.'), @@ -128,15 +128,6 @@ class BaseRunserverCommand(BaseCommand): self.stdout.write("%s\n" % shutdown_message) sys.exit(0) -class Command(BaseRunserverCommand): - option_list = BaseRunserverCommand.option_list + ( - make_option('--adminmedia', dest='admin_media_path', default='', - help='Specifies the directory from which to serve admin media.'), - ) - def get_handler(self, *args, **options): - """ - Serves admin media like old-school (deprecation pending). - """ - handler = super(Command, self).get_handler(*args, **options) - return AdminMediaHandler(handler, options.get('admin_media_path')) +# Kept for backward compatibility +BaseRunserverCommand = Command diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index 8d4ceabfc3..d538ce70e8 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -22,10 +22,6 @@ from django.core.exceptions import ImproperlyConfigured from django.core.management.color import color_style from django.core.wsgi import get_wsgi_application from django.utils.importlib import import_module -from django.utils._os import safe_join -from django.views import static - -from django.contrib.staticfiles import handlers __all__ = ['WSGIServer', 'WSGIRequestHandler'] @@ -131,7 +127,7 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler, object): def __init__(self, *args, **kwargs): from django.conf import settings - self.admin_media_prefix = urlparse.urljoin(settings.STATIC_URL, 'admin/') + self.admin_static_prefix = urlparse.urljoin(settings.STATIC_URL, 'admin/') # We set self.path to avoid crashes in log_message() on unsupported # requests (like "OPTIONS"). self.path = '' @@ -173,7 +169,7 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler, object): def log_message(self, format, *args): # Don't bother logging requests for admin images or the favicon. - if (self.path.startswith(self.admin_media_prefix) + if (self.path.startswith(self.admin_static_prefix) or self.path == '/favicon.ico'): return @@ -200,48 +196,6 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler, object): sys.stderr.write(msg) -class AdminMediaHandler(handlers.StaticFilesHandler): - """ - WSGI middleware that intercepts calls to the admin media directory, as - defined by the STATIC_URL setting, and serves those images. - Use this ONLY LOCALLY, for development! This hasn't been tested for - security and is not super efficient. - - This is pending for deprecation since 1.3. - """ - def get_base_dir(self): - return os.path.join(django.__path__[0], 'contrib', 'admin', 'static', 'admin') - - def get_base_url(self): - from django.conf import settings - return urlparse.urljoin(settings.STATIC_URL, 'admin/') - - def file_path(self, url): - """ - Returns the path to the media file on disk for the given URL. - - The passed URL is assumed to begin with ``self.base_url``. If the - resulting file path is outside the media directory, then a ValueError - is raised. - """ - relative_url = url[len(self.base_url[2]):] - relative_path = urllib.url2pathname(relative_url) - return safe_join(self.base_dir, relative_path) - - def serve(self, request): - document_root, path = os.path.split(self.file_path(request.path)) - return static.serve(request, path, document_root=document_root) - - def _should_handle(self, path): - """ - Checks if the path should be handled. Ignores the path if: - - * the host is provided as part of the base_url - * the request's path isn't under the base path - """ - return path.startswith(self.base_url[2]) and not self.base_url[1] - - def run(addr, port, wsgi_handler, ipv6=False, threading=False): server_address = (addr, port) if threading: diff --git a/docs/howto/deployment/wsgi/gunicorn.txt b/docs/howto/deployment/wsgi/gunicorn.txt index ce9e54d4a6..13d4043e37 100644 --- a/docs/howto/deployment/wsgi/gunicorn.txt +++ b/docs/howto/deployment/wsgi/gunicorn.txt @@ -58,7 +58,7 @@ This provides a few Django-specific niceties: * validates installed models * allows an ``--adminmedia`` option for passing in the location of the - admin media files, mimicing the behavior of runserver. + admin media files. See Gunicorn's `deployment documentation`_ for additional tips on starting and maintaining the Gunicorn server. diff --git a/docs/man/django-admin.1 b/docs/man/django-admin.1 index d336da0f7b..4d937b488b 100644 --- a/docs/man/django-admin.1 +++ b/docs/man/django-admin.1 @@ -70,7 +70,7 @@ Runs this project as a FastCGI application. Requires flup. Use .B runfcgi help for help on the KEY=val pairs. .TP -.BI "runserver [" "\-\-noreload" "] [" "\-\-nothreading" "] [" "\-\-nostatic" "] [" "\-\-insecure" "] [" "\-\-ipv6" "] [" "\-\-adminmedia=ADMIN_MEDIA_PATH" "] [" "port|ipaddr:port" "]" +.BI "runserver [" "\-\-noreload" "] [" "\-\-nothreading" "] [" "\-\-nostatic" "] [" "\-\-insecure" "] [" "\-\-ipv6" "] [" "port|ipaddr:port" "]" Starts a lightweight Web server for development. .TP .BI "shell [" "\-\-plain" "]" @@ -169,9 +169,6 @@ Enables IPv6 addresses. .I \-\-verbosity=VERBOSITY Verbosity level: 0=minimal output, 1=normal output, 2=all output. .TP -.I \-\-adminmedia=ADMIN_MEDIA_PATH -Specifies the directory from which to serve admin media when using the development server. -.TP .I \-\-traceback By default, django-admin.py will show a simple error message whenever an error occurs. If you specify this option, django-admin.py will diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt index f65f302cdb..63e471df0e 100644 --- a/docs/ref/django-admin.txt +++ b/docs/ref/django-admin.txt @@ -655,23 +655,11 @@ You can provide an IPv6 address surrounded by brackets A hostname containing ASCII-only characters can also be used. -.. django-admin-option:: --adminmedia - -Use the ``--adminmedia`` option to tell Django where to find the various CSS -and JavaScript files for the Django admin interface. Normally, the development -server serves these files out of the Django source tree magically, but you'd -want to use this if you made any changes to those files for your own site. - -Example usage:: - - django-admin.py runserver --adminmedia=/tmp/new-admin-style/ - .. versionchanged:: 1.3 If the :doc:`staticfiles` contrib app is enabled (default in new projects) the :djadmin:`runserver` command will be overriden -with an own :djadmin:`runserver` command which doesn't -have the :djadminopt:`--adminmedia` option due to deprecation. +with an own :djadmin:`runserver` command. .. django-admin-option:: --noreload diff --git a/tests/regressiontests/admin_scripts/tests.py b/tests/regressiontests/admin_scripts/tests.py index 68ebda064a..4c4edbbb71 100644 --- a/tests/regressiontests/admin_scripts/tests.py +++ b/tests/regressiontests/admin_scripts/tests.py @@ -1095,12 +1095,12 @@ class ManageTestCommand(AdminScriptTestCase): class ManageRunserver(AdminScriptTestCase): def setUp(self): - from django.core.management.commands.runserver import BaseRunserverCommand + from django.core.management.commands.runserver import Command def monkey_run(*args, **options): return - self.cmd = BaseRunserverCommand() + self.cmd = Command() self.cmd.run = monkey_run def assertServerSettings(self, addr, port, ipv6=None, raw_ipv6=False): diff --git a/tests/regressiontests/admin_widgets/tests.py b/tests/regressiontests/admin_widgets/tests.py index ab6db4d1fb..c1116ba35a 100644 --- a/tests/regressiontests/admin_widgets/tests.py +++ b/tests/regressiontests/admin_widgets/tests.py @@ -20,8 +20,8 @@ from . import models from .widgetadmin import site as widget_admin_site -admin_media_prefix = lambda: { - 'ADMIN_MEDIA_PREFIX': "%sadmin/" % settings.STATIC_URL, +admin_static_prefix = lambda: { + 'ADMIN_STATIC_PREFIX': "%sadmin/" % settings.STATIC_URL, } class AdminFormfieldForDBFieldTests(TestCase): @@ -196,14 +196,14 @@ class FilteredSelectMultipleWidgetTest(DjangoTestCase): w = widgets.FilteredSelectMultiple('test', False) self.assertHTMLEqual( conditional_escape(w.render('test', 'test')), - '\n' % admin_media_prefix() + '\n' % admin_static_prefix() ) def test_stacked_render(self): w = widgets.FilteredSelectMultiple('test', True) self.assertHTMLEqual( conditional_escape(w.render('test', 'test')), - '\n' % admin_media_prefix() + '\n' % admin_static_prefix() ) class AdminDateWidgetTest(DjangoTestCase): @@ -292,7 +292,7 @@ class ForeignKeyRawIdWidgetTest(DjangoTestCase): w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site) self.assertHTMLEqual( conditional_escape(w.render('test', band.pk, attrs={})), - ' Lookup Linkin Park' % dict(admin_media_prefix(), bandpk=band.pk) + ' Lookup Linkin Park' % dict(admin_static_prefix(), bandpk=band.pk) ) def test_relations_to_non_primary_key(self): @@ -307,7 +307,7 @@ class ForeignKeyRawIdWidgetTest(DjangoTestCase): w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site) self.assertHTMLEqual( w.render('test', core.parent_id, attrs={}), - ' Lookup Apple' % admin_media_prefix() + ' Lookup Apple' % admin_static_prefix() ) def test_fk_related_model_not_in_admin(self): @@ -349,7 +349,7 @@ class ForeignKeyRawIdWidgetTest(DjangoTestCase): ) self.assertHTMLEqual( w.render('test', child_of_hidden.parent_id, attrs={}), - ' Lookup Hidden' % admin_media_prefix() + ' Lookup Hidden' % admin_static_prefix() ) @@ -365,12 +365,12 @@ class ManyToManyRawIdWidgetTest(DjangoTestCase): w = widgets.ManyToManyRawIdWidget(rel, widget_admin_site) self.assertHTMLEqual( conditional_escape(w.render('test', [m1.pk, m2.pk], attrs={})), - ' Lookup' % dict(admin_media_prefix(), m1pk=m1.pk, m2pk=m2.pk) + ' Lookup' % dict(admin_static_prefix(), m1pk=m1.pk, m2pk=m2.pk) ) self.assertHTMLEqual( conditional_escape(w.render('test', [m1.pk])), - ' Lookup' % dict(admin_media_prefix(), m1pk=m1.pk) + ' Lookup' % dict(admin_static_prefix(), m1pk=m1.pk) ) self.assertEqual(w._has_changed(None, None), False) @@ -691,4 +691,4 @@ class HorizontalVerticalFilterSeleniumChromeTests(HorizontalVerticalFilterSeleni webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' class HorizontalVerticalFilterSeleniumIETests(HorizontalVerticalFilterSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver' \ No newline at end of file + webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver' diff --git a/tests/regressiontests/servers/tests.py b/tests/regressiontests/servers/tests.py index f127f02959..3a72550011 100644 --- a/tests/regressiontests/servers/tests.py +++ b/tests/regressiontests/servers/tests.py @@ -2,77 +2,15 @@ Tests for django.core.servers. """ import os -from urlparse import urljoin import urllib2 -import django -from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.test import TestCase, LiveServerTestCase -from django.core.handlers.wsgi import WSGIHandler -from django.core.servers.basehttp import AdminMediaHandler, WSGIServerException +from django.test import LiveServerTestCase +from django.core.servers.basehttp import WSGIServerException from django.test.utils import override_settings from .models import Person -class AdminMediaHandlerTests(TestCase): - - def setUp(self): - self.admin_media_url = urljoin(settings.STATIC_URL, 'admin/') - self.admin_media_file_path = os.path.abspath( - os.path.join(django.__path__[0], 'contrib', 'admin', 'static', 'admin') - ) - self.handler = AdminMediaHandler(WSGIHandler()) - - def test_media_urls(self): - """ - Tests that URLs that look like absolute file paths after the - settings.STATIC_URL don't turn into absolute file paths. - """ - # Cases that should work on all platforms. - data = ( - ('%scss/base.css' % self.admin_media_url, ('css', 'base.css')), - ) - # Cases that should raise an exception. - bad_data = () - - # Add platform-specific cases. - if os.sep == '/': - data += ( - # URL, tuple of relative path parts. - ('%s\\css/base.css' % self.admin_media_url, ('\\css', 'base.css')), - ) - bad_data += ( - '%s/css/base.css' % self.admin_media_url, - '%s///css/base.css' % self.admin_media_url, - '%s../css/base.css' % self.admin_media_url, - ) - elif os.sep == '\\': - bad_data += ( - '%sC:\css/base.css' % self.admin_media_url, - '%s/\\css/base.css' % self.admin_media_url, - '%s\\css/base.css' % self.admin_media_url, - '%s\\\\css/base.css' % self.admin_media_url - ) - for url, path_tuple in data: - try: - output = self.handler.file_path(url) - except ValueError: - self.fail("Got a ValueError exception, but wasn't expecting" - " one. URL was: %s" % url) - rel_path = os.path.join(*path_tuple) - desired = os.path.join(self.admin_media_file_path, rel_path) - self.assertEqual( - os.path.normcase(output), os.path.normcase(desired), - "Got: %s, Expected: %s, URL was: %s" % (output, desired, url)) - for url in bad_data: - try: - output = self.handler.file_path(url) - except ValueError: - continue - self.fail('URL: %s should have caused a ValueError exception.' - % url) - TEST_ROOT = os.path.dirname(__file__) TEST_SETTINGS = {