diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 082c11b..2853540 100644
a
|
b
|
class Textarea(Widget):
|
290 | 290 | def render(self, name, value, attrs=None): |
291 | 291 | if value is None: value = '' |
292 | 292 | final_attrs = self.build_attrs(attrs, name=name) |
293 | | return mark_safe(u'<textarea%s>%s</textarea>' % (flatatt(final_attrs), |
| 293 | return mark_safe(u'<textarea%s>\n%s</textarea>' % (flatatt(final_attrs), |
294 | 294 | conditional_escape(force_unicode(value)))) |
295 | 295 | |
296 | 296 | class DateInput(Input): |
diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py
index 1087cf8..dd68ac1 100644
a
|
b
|
Using 'widgets'
|
335 | 335 | ... } |
336 | 336 | |
337 | 337 | >>> str(CategoryForm()['name']) |
338 | | '<textarea id="id_name" rows="10" cols="40" name="name"></textarea>' |
| 338 | '<textarea id="id_name" rows="10" cols="40" name="name">\n</textarea>' |
339 | 339 | |
340 | 340 | >>> str(CategoryForm()['url']) |
341 | 341 | '<input id="id_url" type="text" class="url" name="url" maxlength="40" />' |
… |
… |
fields with the 'choices' attribute are represented by a ChoiceField.
|
543 | 543 | <option value="...">Mike Royko</option> |
544 | 544 | <option value="...">Bob Woodward</option> |
545 | 545 | </select></td></tr> |
546 | | <tr><th>Article:</th><td><textarea rows="10" cols="40" name="article"></textarea></td></tr> |
| 546 | <tr><th>Article:</th><td><textarea rows="10" cols="40" name="article">\n</textarea></td></tr> |
547 | 547 | <tr><th>Status:</th><td><select name="status"> |
548 | 548 | <option value="" selected="selected">---------</option> |
549 | 549 | <option value="1">Draft</option> |
… |
… |
inserted as 'initial' data in each Field.
|
598 | 598 | <option value="..." selected="selected">Mike Royko</option> |
599 | 599 | <option value="...">Bob Woodward</option> |
600 | 600 | </select></li> |
601 | | <li>Article: <textarea rows="10" cols="40" name="article">Hello.</textarea></li> |
| 601 | <li>Article: <textarea rows="10" cols="40" name="article">\nHello.</textarea></li> |
602 | 602 | <li>Status: <select name="status"> |
603 | 603 | <option value="" selected="selected">---------</option> |
604 | 604 | <option value="1">Draft</option> |
… |
… |
Add some categories and test the many-to-many form output.
|
661 | 661 | <option value="..." selected="selected">Mike Royko</option> |
662 | 662 | <option value="...">Bob Woodward</option> |
663 | 663 | </select></li> |
664 | | <li>Article: <textarea rows="10" cols="40" name="article">Hello.</textarea></li> |
| 664 | <li>Article: <textarea rows="10" cols="40" name="article">\nHello.</textarea></li> |
665 | 665 | <li>Status: <select name="status"> |
666 | 666 | <option value="" selected="selected">---------</option> |
667 | 667 | <option value="1">Draft</option> |
… |
… |
Initial values can be provided for model forms
|
685 | 685 | <option value="...">Mike Royko</option> |
686 | 686 | <option value="...">Bob Woodward</option> |
687 | 687 | </select></li> |
688 | | <li>Article: <textarea rows="10" cols="40" name="article"></textarea></li> |
| 688 | <li>Article: <textarea rows="10" cols="40" name="article">\n</textarea></li> |
689 | 689 | <li>Status: <select name="status"> |
690 | 690 | <option value="" selected="selected">---------</option> |
691 | 691 | <option value="1">Draft</option> |
… |
… |
the data in the database when the form is instantiated.
|
801 | 801 | <option value="...">Mike Royko</option> |
802 | 802 | <option value="...">Bob Woodward</option> |
803 | 803 | </select></li> |
804 | | <li>Article: <textarea rows="10" cols="40" name="article"></textarea></li> |
| 804 | <li>Article: <textarea rows="10" cols="40" name="article">\n</textarea></li> |
805 | 805 | <li>Status: <select name="status"> |
806 | 806 | <option value="" selected="selected">---------</option> |
807 | 807 | <option value="1">Draft</option> |
… |
… |
the data in the database when the form is instantiated.
|
827 | 827 | <option value="...">Bob Woodward</option> |
828 | 828 | <option value="...">Carl Bernstein</option> |
829 | 829 | </select></li> |
830 | | <li>Article: <textarea rows="10" cols="40" name="article"></textarea></li> |
| 830 | <li>Article: <textarea rows="10" cols="40" name="article">\n</textarea></li> |
831 | 831 | <li>Status: <select name="status"> |
832 | 832 | <option value="" selected="selected">---------</option> |
833 | 833 | <option value="1">Draft</option> |
diff --git a/tests/regressiontests/forms/forms.py b/tests/regressiontests/forms/forms.py
index bb58eaa..d42381a 100644
a
|
b
|
Any Field can have a Widget class passed to its constructor:
|
321 | 321 | >>> print f['subject'] |
322 | 322 | <input type="text" name="subject" /> |
323 | 323 | >>> print f['message'] |
324 | | <textarea rows="10" cols="40" name="message"></textarea> |
| 324 | <textarea rows="10" cols="40" name="message">\n</textarea> |
325 | 325 | |
326 | 326 | as_textarea(), as_text() and as_hidden() are shortcuts for changing the output |
327 | 327 | widget type: |
328 | 328 | >>> f['subject'].as_textarea() |
329 | | u'<textarea rows="10" cols="40" name="subject"></textarea>' |
| 329 | u'<textarea rows="10" cols="40" name="subject">\n</textarea>' |
330 | 330 | >>> f['message'].as_text() |
331 | 331 | u'<input type="text" name="message" />' |
332 | 332 | >>> f['message'].as_hidden() |
… |
… |
The 'widget' parameter to a Field can also be an instance:
|
338 | 338 | ... message = CharField(widget=Textarea(attrs={'rows': 80, 'cols': 20})) |
339 | 339 | >>> f = ContactForm(auto_id=False) |
340 | 340 | >>> print f['message'] |
341 | | <textarea rows="80" cols="20" name="message"></textarea> |
| 341 | <textarea rows="80" cols="20" name="message">\n</textarea> |
342 | 342 | |
343 | 343 | Instance-level attrs are *not* carried over to as_textarea(), as_text() and |
344 | 344 | as_hidden(): |
… |
… |
as_hidden():
|
346 | 346 | u'<input type="text" name="message" />' |
347 | 347 | >>> f = ContactForm({'subject': 'Hello', 'message': 'I love you.'}, auto_id=False) |
348 | 348 | >>> f['subject'].as_textarea() |
349 | | u'<textarea rows="10" cols="40" name="subject">Hello</textarea>' |
| 349 | u'<textarea rows="10" cols="40" name="subject">\nHello</textarea>' |
350 | 350 | >>> f['message'].as_text() |
351 | 351 | u'<input type="text" name="message" value="I love you." />' |
352 | 352 | >>> f['message'].as_hidden() |
diff --git a/tests/regressiontests/forms/widgets.py b/tests/regressiontests/forms/widgets.py
index cc83a88..759b5bb 100644
a
|
b
|
True
|
243 | 243 | |
244 | 244 | >>> w = Textarea() |
245 | 245 | >>> w.render('msg', '') |
246 | | u'<textarea rows="10" cols="40" name="msg"></textarea>' |
| 246 | u'<textarea rows="10" cols="40" name="msg">\n</textarea>' |
| 247 | |
| 248 | # A textarea should have \n in it. See ticket 13385 |
| 249 | >>> w.render('msg', None).count('\n') == 1 |
| 250 | True |
247 | 251 | >>> w.render('msg', None) |
248 | | u'<textarea rows="10" cols="40" name="msg"></textarea>' |
| 252 | u'<textarea rows="10" cols="40" name="msg">\n</textarea>' |
249 | 253 | >>> w.render('msg', 'value') |
250 | | u'<textarea rows="10" cols="40" name="msg">value</textarea>' |
| 254 | u'<textarea rows="10" cols="40" name="msg">\nvalue</textarea>' |
251 | 255 | >>> w.render('msg', 'some "quoted" & ampersanded value') |
252 | | u'<textarea rows="10" cols="40" name="msg">some "quoted" & ampersanded value</textarea>' |
| 256 | u'<textarea rows="10" cols="40" name="msg">\nsome "quoted" & ampersanded value</textarea>' |
253 | 257 | >>> w.render('msg', mark_safe('pre "quoted" value')) |
254 | | u'<textarea rows="10" cols="40" name="msg">pre "quoted" value</textarea>' |
| 258 | u'<textarea rows="10" cols="40" name="msg">\npre "quoted" value</textarea>' |
255 | 259 | >>> w.render('msg', 'value', attrs={'class': 'pretty', 'rows': 20}) |
256 | | u'<textarea class="pretty" rows="20" cols="40" name="msg">value</textarea>' |
| 260 | u'<textarea class="pretty" rows="20" cols="40" name="msg">\nvalue</textarea>' |
257 | 261 | |
258 | 262 | You can also pass 'attrs' to the constructor: |
259 | 263 | >>> w = Textarea(attrs={'class': 'pretty'}) |
260 | 264 | >>> w.render('msg', '') |
261 | | u'<textarea rows="10" cols="40" name="msg" class="pretty"></textarea>' |
| 265 | u'<textarea rows="10" cols="40" name="msg" class="pretty">\n</textarea>' |
262 | 266 | >>> w.render('msg', 'example') |
263 | | u'<textarea rows="10" cols="40" name="msg" class="pretty">example</textarea>' |
| 267 | u'<textarea rows="10" cols="40" name="msg" class="pretty">\nexample</textarea>' |
264 | 268 | |
265 | 269 | 'attrs' passed to render() get precedence over those passed to the constructor: |
266 | 270 | >>> w = Textarea(attrs={'class': 'pretty'}) |
267 | 271 | >>> w.render('msg', '', attrs={'class': 'special'}) |
268 | | u'<textarea rows="10" cols="40" name="msg" class="special"></textarea>' |
| 272 | u'<textarea rows="10" cols="40" name="msg" class="special">\n</textarea>' |
269 | 273 | |
270 | 274 | >>> w.render('msg', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'}) |
271 | | u'<textarea rows="10" cols="40" name="msg" class="fun">\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</textarea>' |
| 275 | u'<textarea rows="10" cols="40" name="msg" class="fun">\n\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</textarea>' |
272 | 276 | |
273 | 277 | # CheckboxInput Widget ######################################################## |
274 | 278 | |