diff --git a/django/newforms/widgets.py b/django/newforms/widgets.py
index e17e22fa8f..2f157ade75 100644
--- a/django/newforms/widgets.py
+++ b/django/newforms/widgets.py
@@ -14,6 +14,7 @@ from django.utils.html import escape
from django.utils.translation import ugettext
from django.utils.encoding import StrAndUnicode, force_unicode
from util import flatatt
+from urlparse import urljoin
__all__ = (
'Media', 'Widget', 'TextInput', 'PasswordInput',
@@ -62,7 +63,9 @@ class Media(StrAndUnicode):
for medium in media])
def absolute_path(self, path):
- return (path.startswith(u'http://') or path.startswith(u'https://')) and path or u''.join([settings.MEDIA_URL,path])
+ if path.startswith(u'http://') or path.startswith(u'https://') or path.startswith(u'/'):
+ return path
+ return urljoin(settings.MEDIA_URL,path)
def __getitem__(self, name):
"Returns a Media object that only contains media of the given type"
diff --git a/docs/newforms.txt b/docs/newforms.txt
index 19820bc5eb..503bd6634f 100644
--- a/docs/newforms.txt
+++ b/docs/newforms.txt
@@ -2139,17 +2139,21 @@ Paths in media definitions
--------------------------
Paths used to specify media can be either relative or absolute. If a path
-starts with 'http://' or 'https://', it will be interpreted as an absolute
+starts with '/', 'http://' or 'https://', it will be interpreted as an absolute
path, and left as-is. All other paths will be prepended with the value of
``settings.MEDIA_URL``. For example, if the MEDIA_URL for your site was
``http://media.example.com/``::
class CalendarWidget(forms.TextInput):
class Media:
+ css = {
+ 'all': ('/css/pretty.css',),
+ }
js = ('animations.js', 'http://othersite.com/actions.js')
>>> w = CalendarWidget()
>>> print w.media
+
diff --git a/tests/regressiontests/forms/media.py b/tests/regressiontests/forms/media.py
index f9b0fbc492..4c87f617a4 100644
--- a/tests/regressiontests/forms/media.py
+++ b/tests/regressiontests/forms/media.py
@@ -4,35 +4,35 @@
media_tests = r"""
>>> from django.newforms import TextInput, Media, TextInput, CharField, Form, MultiWidget
>>> from django.conf import settings
->>> settings.MEDIA_URL = 'http://media.example.com'
+>>> settings.MEDIA_URL = 'http://media.example.com/media/'
# Check construction of media objects
->>> m = Media(css={'all': ('/path/to/css1','/path/to/css2')}, js=('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3'))
+>>> m = Media(css={'all': ('path/to/css1','/path/to/css2')}, js=('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3'))
>>> print m
-
-
-
+
+
+
>>> class Foo:
... css = {
-... 'all': ('/path/to/css1','/path/to/css2')
+... 'all': ('path/to/css1','/path/to/css2')
... }
... js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')
>>> m3 = Media(Foo)
>>> print m3
-
-
-
+
+
+
>>> m3 = Media(Foo)
>>> print m3
-
-
-
+
+
+
@@ -54,25 +54,25 @@ media_tests = r"""
>>> class MyWidget1(TextInput):
... class Media:
... css = {
-... 'all': ('/path/to/css1','/path/to/css2')
+... 'all': ('path/to/css1','/path/to/css2')
... }
... js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')
>>> w1 = MyWidget1()
>>> print w1.media
-
-
-
+
+
+
# Media objects can be interrogated by media type
>>> print w1.media['css']
-
-
+
+
>>> print w1.media['js']
-
+
@@ -88,26 +88,26 @@ media_tests = r"""
>>> class MyWidget3(TextInput):
... class Media:
... css = {
-... 'all': ('/path/to/css3','/path/to/css1')
+... 'all': ('/path/to/css3','path/to/css1')
... }
... js = ('/path/to/js1','/path/to/js4')
>>> w2 = MyWidget2()
>>> w3 = MyWidget3()
>>> print w1.media + w2.media + w3.media
-
-
-
-
+
+
+
+
-
+
# Check that media addition hasn't affected the original objects
>>> print w1.media
-
-
-
+
+
+
@@ -123,8 +123,8 @@ media_tests = r"""
>>> w4 = MyWidget4()
>>> print w4.media
-
-
+
+
# Media properties can reference the media of their parents
>>> class MyWidget5(MyWidget4):
@@ -134,10 +134,10 @@ media_tests = r"""
>>> w5 = MyWidget5()
>>> print w5.media
-
-
-
-
+
+
+
+
# Media properties can reference the media of their parents,
# even if the parent media was defined using a class
@@ -148,13 +148,13 @@ media_tests = r"""
>>> w6 = MyWidget6()
>>> print w6.media
-
-
-
-
+
+
+
+
-
+
###############################################################
# Inheritance of media
@@ -166,9 +166,9 @@ media_tests = r"""
>>> w7 = MyWidget7()
>>> print w7.media
-
-
-
+
+
+
@@ -176,19 +176,19 @@ media_tests = r"""
>>> class MyWidget8(MyWidget1):
... class Media:
... css = {
-... 'all': ('/path/to/css3','/path/to/css1')
+... 'all': ('/path/to/css3','path/to/css1')
... }
... js = ('/path/to/js1','/path/to/js4')
>>> w8 = MyWidget8()
>>> print w8.media
-
-
-
-
+
+
+
+
-
+
# If a widget extends another but defines media, it extends the parents widget's media,
# even if the parent defined media using a property.
@@ -201,62 +201,62 @@ media_tests = r"""
>>> w9 = MyWidget9()
>>> print w9.media
-
-
-
-
+
+
+
+
# A widget can disable media inheritance by specifying 'extend=False'
>>> class MyWidget10(MyWidget1):
... class Media:
... extend = False
... css = {
-... 'all': ('/path/to/css3','/path/to/css1')
+... 'all': ('/path/to/css3','path/to/css1')
... }
... js = ('/path/to/js1','/path/to/js4')
>>> w10 = MyWidget10()
>>> print w10.media
-
-
-
-
+
+
+
+
# A widget can explicitly enable full media inheritance by specifying 'extend=True'
>>> class MyWidget11(MyWidget1):
... class Media:
... extend = True
... css = {
-... 'all': ('/path/to/css3','/path/to/css1')
+... 'all': ('/path/to/css3','path/to/css1')
... }
... js = ('/path/to/js1','/path/to/js4')
>>> w11 = MyWidget11()
>>> print w11.media
-
-
-
-
+
+
+
+
-
+
# A widget can enable inheritance of one media type by specifying extend as a tuple
>>> class MyWidget12(MyWidget1):
... class Media:
... extend = ('css',)
... css = {
-... 'all': ('/path/to/css3','/path/to/css1')
+... 'all': ('/path/to/css3','path/to/css1')
... }
... js = ('/path/to/js1','/path/to/js4')
>>> w12 = MyWidget12()
>>> print w12.media
-
-
-
-
-
+
+
+
+
+
###############################################################
# Multi-media handling for CSS
@@ -274,12 +274,12 @@ media_tests = r"""
>>> multimedia = MultimediaWidget()
>>> print multimedia.media
-
-
-
-
-
-
+
+
+
+
+
+
###############################################################
# Multiwidget media handling
@@ -294,13 +294,13 @@ media_tests = r"""
>>> mymulti = MyMultiWidget()
>>> print mymulti.media
-
-
-
-
+
+
+
+
-
+
###############################################################
# Media processing for forms
@@ -312,26 +312,26 @@ media_tests = r"""
... field2 = CharField(max_length=20, widget=MyWidget2())
>>> f1 = MyForm()
>>> print f1.media
-
-
-
-
+
+
+
+
-
+
# Form media can be combined to produce a single media definition.
>>> class AnotherForm(Form):
... field3 = CharField(max_length=20, widget=MyWidget3())
>>> f2 = AnotherForm()
>>> print f1.media + f2.media
-
-
-
-
+
+
+
+
-
+
# Forms can also define media, following the same rules as widgets.
>>> class FormWithMedia(Form):
@@ -344,14 +344,14 @@ media_tests = r"""
... }
>>> f3 = FormWithMedia()
>>> print f3.media
-
-
-
-
-
+
+
+
+
+
-
-
+
+
"""
\ No newline at end of file