Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.5.x] Fixed #8627 -- Prevented textareas to swallow first newline c…

…ontent

Browsers consider the first newline in textareas as some display
artifact, not real content. Hence they are not sending it back to
the server. If we want to keep initial newlines, we have to add one
when we render the textarea.
Thanks bastih for the report and initial patch.

Backport of 78f6669 from master.
  • Loading branch information...
commit a23c9c48a81e8efadeeb91d1403c9d797a348fe7 1 parent c7d5e7c
Claude Paroz authored November 05, 2012
2  django/forms/widgets.py
@@ -403,7 +403,7 @@ def __init__(self, attrs=None):
403 403
     def render(self, name, value, attrs=None):
404 404
         if value is None: value = ''
405 405
         final_attrs = self.build_attrs(attrs, name=name)
406  
-        return format_html('<textarea{0}>{1}</textarea>',
  406
+        return format_html('<textarea{0}>\r\n{1}</textarea>',
407 407
                            flatatt(final_attrs),
408 408
                            force_text(value))
409 409
 
6  tests/regressiontests/forms/models.py
@@ -83,4 +83,8 @@ def __str__(self):
83 83
 
84 84
 
85 85
 class Cheese(models.Model):
86  
-   name = models.CharField(max_length=100)
  86
+    name = models.CharField(max_length=100)
  87
+
  88
+
  89
+class Article(models.Model):
  90
+    content = models.TextField()
8  tests/regressiontests/forms/templates/forms/article_form.html
... ...
@@ -0,0 +1,8 @@
  1
+<html>
  2
+<body>
  3
+  <form method="post" action=".">
  4
+    {{ form.as_p }}<br>
  5
+    <input id="submit" type="submit">
  6
+  </form>
  7
+</body>
  8
+</html>
2  tests/regressiontests/forms/tests/__init__.py
@@ -18,4 +18,4 @@
18 18
 from .util import FormsUtilTestCase
19 19
 from .validators import TestFieldWithValidators
20 20
 from .widgets import (FormsWidgetTestCase, FormsI18NWidgetsTestCase,
21  
-    WidgetTests, ClearableFileInputTests)
  21
+    WidgetTests, LiveWidgetTests, ClearableFileInputTests)
20  tests/regressiontests/forms/tests/widgets.py
@@ -4,7 +4,9 @@
4 4
 import copy
5 5
 import datetime
6 6
 
  7
+from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase
7 8
 from django.core.files.uploadedfile import SimpleUploadedFile
  9
+from django.core.urlresolvers import reverse
8 10
 from django.forms import *
9 11
 from django.forms.widgets import RadioFieldRenderer
10 12
 from django.utils import formats
@@ -15,6 +17,8 @@
15 17
 from django.test.utils import override_settings
16 18
 from django.utils.encoding import python_2_unicode_compatible
17 19
 
  20
+from ..models import Article
  21
+
18 22
 
19 23
 class FormsWidgetTestCase(TestCase):
20 24
     # Each Widget class corresponds to an HTML form widget. A Widget knows how to
@@ -1095,6 +1099,22 @@ class SplitDateRequiredForm(Form):
1095 1099
         self.assertFalse(form.is_valid())
1096 1100
 
1097 1101
 
  1102
+class LiveWidgetTests(AdminSeleniumWebDriverTestCase):
  1103
+    urls = 'regressiontests.forms.urls'
  1104
+
  1105
+    def test_textarea_trailing_newlines(self):
  1106
+        """
  1107
+        Test that a roundtrip on a ModelForm doesn't alter the TextField value
  1108
+        """
  1109
+        article = Article.objects.create(content="\nTst\n")
  1110
+        self.selenium.get('%s%s' % (self.live_server_url,
  1111
+            reverse('article_form', args=[article.pk])))
  1112
+        self.selenium.find_element_by_id('submit').submit()
  1113
+        article = Article.objects.get(pk=article.pk)
  1114
+        # Should be "\nTst\n" after #19251 is fixed
  1115
+        self.assertEqual(article.content, "\r\nTst\r\n")
  1116
+
  1117
+
1098 1118
 @python_2_unicode_compatible
1099 1119
 class FakeFieldFile(object):
1100 1120
     """
9  tests/regressiontests/forms/urls.py
... ...
@@ -0,0 +1,9 @@
  1
+from django.conf.urls import patterns, url
  2
+from django.views.generic.edit import UpdateView
  3
+
  4
+from .views import ArticleFormView
  5
+
  6
+
  7
+urlpatterns = patterns('',
  8
+    url(r'^/model_form/(?P<pk>\d+)/$', ArticleFormView.as_view(), name="article_form"),
  9
+)
8  tests/regressiontests/forms/views.py
... ...
@@ -0,0 +1,8 @@
  1
+from django.views.generic.edit import UpdateView
  2
+
  3
+from .models import Article
  4
+
  5
+
  6
+class ArticleFormView(UpdateView):
  7
+    model = Article
  8
+    success_url = '/'

0 notes on commit a23c9c4

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