Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #17549 -- Added a clickable link for URLFields in admin change …

…list.
  • Loading branch information...
commit ac2052ebc84c45709ab5f0f25e685bf656ce79bc 1 parent 39f5bc7
Ulrich Petri authored July 07, 2012 apollo13 committed November 03, 2012
15  django/contrib/admin/static/admin/css/widgets.css
@@ -225,6 +225,21 @@ table p.datetime {
225 225
     padding-left: 0;
226 226
 }
227 227
 
  228
+/* URL */
  229
+
  230
+p.url {
  231
+    line-height: 20px;
  232
+    margin: 0;
  233
+    padding: 0;
  234
+    color: #666;
  235
+    font-size: 11px;
  236
+    font-weight: bold;
  237
+}
  238
+
  239
+.url a {
  240
+    font-weight: normal;
  241
+}
  242
+
228 243
 /* FILE UPLOADS */
229 244
 
230 245
 p.file-upload {
15  django/contrib/admin/widgets.py
@@ -10,7 +10,7 @@
10 10
 from django.core.urlresolvers import reverse
11 11
 from django.forms.widgets import RadioFieldRenderer
12 12
 from django.forms.util import flatatt
13  
-from django.utils.html import escape, format_html, format_html_join
  13
+from django.utils.html import escape, format_html, format_html_join, smart_urlquote
14 14
 from django.utils.text import Truncator
15 15
 from django.utils.translation import ugettext as _
16 16
 from django.utils.safestring import mark_safe
@@ -306,6 +306,19 @@ def __init__(self, attrs=None):
306 306
             final_attrs.update(attrs)
307 307
         super(AdminURLFieldWidget, self).__init__(attrs=final_attrs)
308 308
 
  309
+    def render(self, name, value, attrs=None):
  310
+        html = super(AdminURLFieldWidget, self).render(name, value, attrs)
  311
+        if value:
  312
+            value = force_text(self._format_value(value))
  313
+            final_attrs = {'href': mark_safe(smart_urlquote(value))}
  314
+            html = format_html(
  315
+                '<p class="url">{0} <a {1}>{2}</a><br />{3} {4}</p>',
  316
+                _('Currently:'), flatatt(final_attrs), value,
  317
+                _('Change:'), html
  318
+            )
  319
+        return html
  320
+
  321
+
309 322
 class AdminIntegerFieldWidget(forms.TextInput):
310 323
     class_name = 'vIntegerField'
311 324
 
5  docs/ref/models/fields.txt
@@ -922,6 +922,11 @@ Like all :class:`CharField` subclasses, :class:`URLField` takes the optional
922 922
 :attr:`~CharField.max_length`argument. If you don't specify
923 923
 :attr:`~CharField.max_length`, a default of 200 is used.
924 924
 
  925
+.. versionadded:: 1.5
  926
+
  927
+The current value of the field will be displayed as a clickable link above the
  928
+input widget.
  929
+
925 930
 
926 931
 Relationship fields
927 932
 ===================
31  tests/regressiontests/admin_widgets/tests.py
@@ -266,6 +266,37 @@ def test_localization(self):
266 266
                 )
267 267
 
268 268
 
  269
+class AdminURLWidgetTest(DjangoTestCase):
  270
+    def test_render(self):
  271
+        w = widgets.AdminURLFieldWidget()
  272
+        self.assertHTMLEqual(
  273
+            conditional_escape(w.render('test', '')),
  274
+            '<input class="vURLField" name="test" type="text" />'
  275
+        )
  276
+        self.assertHTMLEqual(
  277
+            conditional_escape(w.render('test', 'http://example.com')),
  278
+            '<p class="url">Currently:<a href="http://example.com">http://example.com</a><br />Change:<input class="vURLField" name="test" type="text" value="http://example.com" /></p>'
  279
+        )
  280
+
  281
+    def test_render_idn(self):
  282
+        w = widgets.AdminURLFieldWidget()
  283
+        self.assertHTMLEqual(
  284
+            conditional_escape(w.render('test', 'http://example-äüö.com')),
  285
+            '<p class="url">Currently:<a href="http://xn--example--7za4pnc.com">http://example-äüö.com</a><br />Change:<input class="vURLField" name="test" type="text" value="http://example-äüö.com" /></p>'
  286
+        )
  287
+
  288
+    def test_render_quoting(self):
  289
+        w = widgets.AdminURLFieldWidget()
  290
+        self.assertHTMLEqual(
  291
+            conditional_escape(w.render('test', 'http://example.com/<sometag>some text</sometag>')),
  292
+            '<p class="url">Currently:<a href="http://example.com/%3Csometag%3Esome%20text%3C/sometag%3E">http://example.com/&lt;sometag&gt;some text&lt;/sometag&gt;</a><br />Change:<input class="vURLField" name="test" type="text" value="http://example.com/<sometag>some text</sometag>" /></p>'
  293
+        )
  294
+        self.assertHTMLEqual(
  295
+            conditional_escape(w.render('test', 'http://example-äüö.com/<sometag>some text</sometag>')),
  296
+            '<p class="url">Currently:<a href="http://xn--example--7za4pnc.com/%3Csometag%3Esome%20text%3C/sometag%3E">http://example-äüö.com/&lt;sometag&gt;some text&lt;/sometag&gt;</a><br />Change:<input class="vURLField" name="test" type="text" value="http://example-äüö.com/<sometag>some text</sometag>" /></p>'
  297
+        )
  298
+
  299
+
269 300
 class AdminFileWidgetTest(DjangoTestCase):
270 301
     def test_render(self):
271 302
         band = models.Band.objects.create(name='Linkin Park')

0 notes on commit ac2052e

Please sign in to comment.
Something went wrong with that request. Please try again.