diff --git a/django/forms/widgets.py b/django/forms/widgets.py index 365b7ba8c0..3e6de0455c 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -81,11 +81,7 @@ class Media(object): if path.startswith(('http://', 'https://', '/')): return path if prefix is None: - if settings.STATIC_URL is None: - # backwards compatibility - prefix = settings.MEDIA_URL - else: - prefix = settings.STATIC_URL + prefix = settings.STATIC_URL return urljoin(prefix, path) def __getitem__(self, name): diff --git a/tests/forms_tests/tests/test_media.py b/tests/forms_tests/tests/test_media.py index f48983779c..945d9d059a 100644 --- a/tests/forms_tests/tests/test_media.py +++ b/tests/forms_tests/tests/test_media.py @@ -6,536 +6,11 @@ from django.utils.encoding import force_text @override_settings( - STATIC_URL=None, - MEDIA_URL='http://media.example.com/media/', + STATIC_URL='http://media.example.com/static/', ) class FormsMediaTestCase(SimpleTestCase): """Tests for the media handling on widgets and forms""" - def test_construction(self): - # 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'), - ) - self.assertEqual( - str(m), - """ - - - -""" - ) - - class Foo: - 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') - - m3 = Media(Foo) - self.assertEqual( - str(m3), - """ - - - -""" - ) - - # A widget can exist without a media definition - class MyWidget(TextInput): - pass - - w = MyWidget() - self.assertEqual(str(w.media), '') - - def test_media_dsl(self): - ############################################################### - # DSL Class-based media definitions - ############################################################### - - # A widget can define media if it needs to. - # Any absolute path will be preserved; relative paths are combined - # with the value of settings.MEDIA_URL - class MyWidget1(TextInput): - class 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') - - w1 = MyWidget1() - self.assertEqual( - str(w1.media), - """ - - - -""" - ) - - # Media objects can be interrogated by media type - self.assertEqual( - str(w1.media['css']), - """ -""") - - self.assertEqual( - str(w1.media['js']), - """ - -""" - ) - - def test_combine_media(self): - # Media objects can be combined. Any given media resource will appear only - # once. Duplicated media definitions are ignored. - class MyWidget1(TextInput): - class 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') - - class MyWidget2(TextInput): - class Media: - css = { - 'all': ('/path/to/css2', '/path/to/css3') - } - js = ('/path/to/js1', '/path/to/js4') - - class MyWidget3(TextInput): - class Media: - css = { - 'all': ('/path/to/css3', 'path/to/css1') - } - js = ('/path/to/js1', '/path/to/js4') - - w1 = MyWidget1() - w2 = MyWidget2() - w3 = MyWidget3() - self.assertEqual( - str(w1.media + w2.media + w3.media), - """ - - - - - -""" - ) - - # Check that media addition hasn't affected the original objects - self.assertEqual( - str(w1.media), - """ - - - -""" - ) - - # Regression check for #12879: specifying the same CSS or JS file - # multiple times in a single Media instance should result in that file - # only being included once. - class MyWidget4(TextInput): - class Media: - css = {'all': ('/path/to/css1', '/path/to/css1')} - js = ('/path/to/js1', '/path/to/js1') - - w4 = MyWidget4() - self.assertEqual( - str(w4.media), - """ -""" - ) - - def test_media_property(self): - ############################################################### - # Property-based media definitions - ############################################################### - - # Widget media can be defined as a property - class MyWidget4(TextInput): - def _media(self): - return Media(css={'all': ('/some/path',)}, js=('/some/js',)) - media = property(_media) - - w4 = MyWidget4() - self.assertEqual(str(w4.media), """ -""") - - # Media properties can reference the media of their parents - class MyWidget5(MyWidget4): - def _media(self): - return super(MyWidget5, self).media + Media(css={'all': ('/other/path',)}, js=('/other/js',)) - media = property(_media) - - w5 = MyWidget5() - self.assertEqual( - str(w5.media), - """ - - -""" - ) - - def test_media_property_parent_references(self): - # Media properties can reference the media of their parents, - # even if the parent media was defined using a class - class MyWidget1(TextInput): - class 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') - - class MyWidget6(MyWidget1): - def _media(self): - return super(MyWidget6, self).media + Media(css={'all': ('/other/path',)}, js=('/other/js',)) - media = property(_media) - - w6 = MyWidget6() - self.assertEqual( - str(w6.media), - """ - - - - - -""" - ) - - def test_media_inheritance(self): - ############################################################### - # Inheritance of media - ############################################################### - - # If a widget extends another but provides no media definition, it inherits the parent widget's media - class MyWidget1(TextInput): - class 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') - - class MyWidget7(MyWidget1): - pass - - w7 = MyWidget7() - self.assertEqual( - str(w7.media), - """ - - - -""" - ) - - # If a widget extends another but defines media, it extends the parent widget's media by default - class MyWidget8(MyWidget1): - class Media: - css = { - 'all': ('/path/to/css3', 'path/to/css1') - } - js = ('/path/to/js1', '/path/to/js4') - - w8 = MyWidget8() - self.assertEqual( - str(w8.media), - """ - - - - - -""" - ) - - def test_media_inheritance_from_property(self): - # If a widget extends another but defines media, it extends the parents widget's media, - # even if the parent defined media using a property. - class MyWidget1(TextInput): - class 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') - - class MyWidget4(TextInput): - def _media(self): - return Media(css={'all': ('/some/path',)}, js=('/some/js',)) - media = property(_media) - - class MyWidget9(MyWidget4): - class Media: - css = { - 'all': ('/other/path',) - } - js = ('/other/js',) - - w9 = MyWidget9() - self.assertEqual( - str(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') - } - js = ('/path/to/js1', '/path/to/js4') - - w10 = MyWidget10() - self.assertEqual(str(w10.media), """ - - -""") - - def test_media_inheritance_extends(self): - # A widget can explicitly enable full media inheritance by specifying 'extend=True' - class MyWidget1(TextInput): - class 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') - - class MyWidget11(MyWidget1): - class Media: - extend = True - css = { - 'all': ('/path/to/css3', 'path/to/css1') - } - js = ('/path/to/js1', '/path/to/js4') - - w11 = MyWidget11() - self.assertEqual( - str(w11.media), - """ - - - - - -""" - ) - - def test_media_inheritance_single_type(self): - # A widget can enable inheritance of one media type by specifying extend as a tuple - class MyWidget1(TextInput): - class 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') - - class MyWidget12(MyWidget1): - class Media: - extend = ('css',) - css = { - 'all': ('/path/to/css3', 'path/to/css1') - } - js = ('/path/to/js1', '/path/to/js4') - - w12 = MyWidget12() - self.assertEqual( - str(w12.media), - """ - - - -""" - ) - - def test_multi_media(self): - ############################################################### - # Multi-media handling for CSS - ############################################################### - - # A widget can define CSS media for multiple output media types - class MultimediaWidget(TextInput): - class Media: - css = { - 'screen, print': ('/file1', '/file2'), - 'screen': ('/file3',), - 'print': ('/file4',) - } - js = ('/path/to/js1', '/path/to/js4') - - multimedia = MultimediaWidget() - self.assertEqual( - str(multimedia.media), - """ - - - - -""" - ) - - def test_multi_widget(self): - ############################################################### - # Multiwidget media handling - ############################################################### - - class MyWidget1(TextInput): - class 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') - - class MyWidget2(TextInput): - class Media: - css = { - 'all': ('/path/to/css2', '/path/to/css3') - } - js = ('/path/to/js1', '/path/to/js4') - - class MyWidget3(TextInput): - class Media: - css = { - 'all': ('/path/to/css3', 'path/to/css1') - } - js = ('/path/to/js1', '/path/to/js4') - - # MultiWidgets have a default media definition that gets all the - # media from the component widgets - class MyMultiWidget(MultiWidget): - def __init__(self, attrs=None): - widgets = [MyWidget1, MyWidget2, MyWidget3] - super(MyMultiWidget, self).__init__(widgets, attrs) - - mymulti = MyMultiWidget() - self.assertEqual( - str(mymulti.media), - """ - - - - - -""" - ) - - def test_form_media(self): - ############################################################### - # Media processing for forms - ############################################################### - - class MyWidget1(TextInput): - class 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') - - class MyWidget2(TextInput): - class Media: - css = { - 'all': ('/path/to/css2', '/path/to/css3') - } - js = ('/path/to/js1', '/path/to/js4') - - class MyWidget3(TextInput): - class Media: - css = { - 'all': ('/path/to/css3', 'path/to/css1') - } - js = ('/path/to/js1', '/path/to/js4') - - # You can ask a form for the media required by its widgets. - class MyForm(Form): - field1 = CharField(max_length=20, widget=MyWidget1()) - field2 = CharField(max_length=20, widget=MyWidget2()) - f1 = MyForm() - self.assertEqual( - str(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() - self.assertEqual( - str(f1.media + f2.media), - """ - - - - - -""" - ) - - # Forms can also define media, following the same rules as widgets. - class FormWithMedia(Form): - field1 = CharField(max_length=20, widget=MyWidget1()) - field2 = CharField(max_length=20, widget=MyWidget2()) - - class Media: - js = ('/some/form/javascript',) - css = { - 'all': ('/some/form/css',) - } - f3 = FormWithMedia() - self.assertEqual( - str(f3.media), - """ - - - - - - - -""" - ) - - # Media works in templates - self.assertEqual( - Template("{{ form.media.js }}{{ form.media.css }}").render(Context({'form': f3})), - """ - - - -""" - """ - - -""" - ) - - def test_html_safe(self): - media = Media(css={'all': ['/path/to/css']}, js=['/path/to/js']) - self.assertTrue(hasattr(Media, '__html__')) - self.assertEqual(force_text(media), media.__html__()) - - -@override_settings( - STATIC_URL='http://media.example.com/static/', - MEDIA_URL='http://media.example.com/media/', -) -class StaticFormsMediaTestCase(SimpleTestCase): - """Tests for the media handling on widgets and forms""" - def test_construction(self): # Check construction of media objects m = Media( @@ -1040,3 +515,8 @@ class StaticFormsMediaTestCase(SimpleTestCase): """ ) + + def test_html_safe(self): + media = Media(css={'all': ['/path/to/css']}, js=['/path/to/js']) + self.assertTrue(hasattr(Media, '__html__')) + self.assertEqual(force_text(media), media.__html__())