Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixes #10427 -- Abstract the value generation of a BoundField

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14734 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit d3f5f219f5f42ac3504ed626dcb92f4ee2dc3d5f 1 parent e74edb4
Chris Beaven authored November 28, 2010
26  django/forms/forms.py
@@ -432,20 +432,11 @@ def as_widget(self, widget=None, attrs=None, only_initial=False):
432 432
             else:
433 433
                 attrs['id'] = self.html_initial_id
434 434
 
435  
-        if not self.form.is_bound:
436  
-            data = self.form.initial.get(self.name, self.field.initial)
437  
-            if callable(data):
438  
-                data = data()
439  
-        else:
440  
-            data = self.field.bound_data(
441  
-                self.data, self.form.initial.get(self.name, self.field.initial))
442  
-        data = self.field.prepare_value(data)
443  
-
444 435
         if not only_initial:
445 436
             name = self.html_name
446 437
         else:
447 438
             name = self.html_initial_name
448  
-        return widget.render(name, data, attrs=attrs)
  439
+        return widget.render(name, self.value(), attrs=attrs)
449 440
 
450 441
     def as_text(self, attrs=None, **kwargs):
451 442
         """
@@ -470,6 +461,21 @@ def _data(self):
470 461
         return self.field.widget.value_from_datadict(self.form.data, self.form.files, self.html_name)
471 462
     data = property(_data)
472 463
 
  464
+    def value(self):
  465
+        """
  466
+        Returns the value for this BoundField, using the initial value if
  467
+        the form is not bound or the data otherwise.
  468
+        """
  469
+        if not self.form.is_bound:
  470
+            data = self.form.initial.get(self.name, self.field.initial)
  471
+            if callable(data):
  472
+                data = data()
  473
+        else:
  474
+            data = self.field.bound_data(
  475
+                self.data, self.form.initial.get(self.name, self.field.initial)
  476
+            )
  477
+        return self.field.prepare_value(data)
  478
+
473 479
     def label_tag(self, contents=None, attrs=None):
474 480
         """
475 481
         Wraps the given contents in a <label>, if the field has an ID attribute.
97  docs/ref/forms/api.txt
@@ -584,36 +584,29 @@ More granular output
584 584
 The ``as_p()``, ``as_ul()`` and ``as_table()`` methods are simply shortcuts for
585 585
 lazy developers -- they're not the only way a form object can be displayed.
586 586
 
587  
-To display the HTML for a single field in your form, use dictionary lookup
588  
-syntax using the field's name as the key, and print the resulting object::
  587
+.. class:: BoundField
589 588
 
590  
-    >>> f = ContactForm()
591  
-    >>> print f['subject']
592  
-    <input id="id_subject" type="text" name="subject" maxlength="100" />
593  
-    >>> print f['message']
594  
-    <input type="text" name="message" id="id_message" />
595  
-    >>> print f['sender']
596  
-    <input type="text" name="sender" id="id_sender" />
597  
-    >>> print f['cc_myself']
598  
-    <input type="checkbox" name="cc_myself" id="id_cc_myself" />
  589
+   Used to display HTML or access attributes for a single field of a
  590
+   :class:`Form` instance.
  591
+   
  592
+   The :meth:`__unicode__` and :meth:`__str__` methods of this object displays
  593
+   the HTML for this field.
599 594
 
600  
-Call ``str()`` or ``unicode()`` on the field to get its rendered HTML as a
601  
-string or Unicode object, respectively::
  595
+To retrieve a single ``BoundField``, use dictionary lookup syntax on your form
  596
+using the field's name as the key::
602 597
 
603  
-    >>> str(f['subject'])
604  
-    '<input id="id_subject" type="text" name="subject" maxlength="100" />'
605  
-    >>> unicode(f['subject'])
606  
-    u'<input id="id_subject" type="text" name="subject" maxlength="100" />'
  598
+	>>> form = ContactForm()
  599
+	>>> print form['subject']
  600
+	<input id="id_subject" type="text" name="subject" maxlength="100" />
607 601
 
608  
-Form objects define a custom ``__iter__()`` method, which allows you to loop
609  
-through their fields::
  602
+To retrieve all ``BoundField`` objects, iterate the form::
610 603
 
611  
-    >>> f = ContactForm()
612  
-    >>> for field in f: print field
613  
-    <input id="id_subject" type="text" name="subject" maxlength="100" />
614  
-    <input type="text" name="message" id="id_message" />
615  
-    <input type="text" name="sender" id="id_sender" />
616  
-    <input type="checkbox" name="cc_myself" id="id_cc_myself" />
  604
+	>>> form = ContactForm()
  605
+	>>> for boundfield in form: print boundfield
  606
+	<input id="id_subject" type="text" name="subject" maxlength="100" />
  607
+	<input type="text" name="message" id="id_message" />
  608
+	<input type="text" name="sender" id="id_sender" />
  609
+	<input type="checkbox" name="cc_myself" id="id_cc_myself" />
617 610
 
618 611
 The field-specific output honors the form object's ``auto_id`` setting::
619 612
 
@@ -624,26 +617,31 @@ The field-specific output honors the form object's ``auto_id`` setting::
624 617
     >>> print f['message']
625 618
     <input type="text" name="message" id="id_message" />
626 619
 
627  
-For a field's list of errors, access the field's ``errors`` attribute. This
628  
-is a list-like object that is displayed as an HTML ``<ul class="errorlist">``
629  
-when printed::
  620
+For a field's list of errors, access the field's ``errors`` attribute.
630 621
 
631  
-    >>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''}
632  
-    >>> f = ContactForm(data, auto_id=False)
633  
-    >>> print f['message']
634  
-    <input type="text" name="message" />
635  
-    >>> f['message'].errors
636  
-    [u'This field is required.']
637  
-    >>> print f['message'].errors
638  
-    <ul class="errorlist"><li>This field is required.</li></ul>
639  
-    >>> f['subject'].errors
640  
-    []
641  
-    >>> print f['subject'].errors
  622
+.. attribute:: BoundField.errors
642 623
 
643  
-    >>> str(f['subject'].errors)
644  
-    ''
  624
+    A list-like object that is displayed as an HTML ``<ul class="errorlist">``
  625
+    when printed::
645 626
 
646  
-.. versionadded:: 1.2
  627
+        >>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''}
  628
+        >>> f = ContactForm(data, auto_id=False)
  629
+        >>> print f['message']
  630
+        <input type="text" name="message" />
  631
+        >>> f['message'].errors
  632
+        [u'This field is required.']
  633
+        >>> print f['message'].errors
  634
+        <ul class="errorlist"><li>This field is required.</li></ul>
  635
+        >>> f['subject'].errors
  636
+        []
  637
+        >>> print f['subject'].errors
  638
+
  639
+        >>> str(f['subject'].errors)
  640
+	    ''
  641
+
  642
+.. method:: BoundField.css_classes()
  643
+
  644
+   .. versionadded:: 1.2
647 645
 
648 646
 When you use Django's rendering shortcuts, CSS classes are used to
649 647
 indicate required form fields or fields that contain errors. If you're
@@ -662,6 +660,21 @@ those classes as an argument::
662 660
 	>>> f['message'].css_classes('foo bar')
663 661
 	'foo bar required'
664 662
 
  663
+.. method:: BoundField.values()
  664
+
  665
+   .. versionadded:: 1.3
  666
+
  667
+Use this method to render the raw value of this field as it would be rendered
  668
+by a ``Widget``::
  669
+
  670
+    >>> initial = {'subject': 'welcome'}
  671
+    >>> unbound_form = ContactForm(initial=initial)
  672
+    >>> bound_form = ContactForm(data, initial=initial)
  673
+    >>> print unbound_form['subject'].value
  674
+    welcome
  675
+    >>> print bound_form['subject'].value
  676
+    hi
  677
+
665 678
 .. _binding-uploaded-files:
666 679
 
667 680
 Binding uploaded files to a form
15  tests/regressiontests/forms/tests/forms.py
@@ -1151,6 +1151,21 @@ class UserRegistration(Form):
1151 1151
 <option value="w">whiz</option>
1152 1152
 </select></li>""")
1153 1153
 
  1154
+    def test_boundfield_values(self):
  1155
+        # It's possible to get to the value which would be used for rendering
  1156
+        # the widget for a field by using the BoundField's value method.
  1157
+ 
  1158
+        class UserRegistration(Form):
  1159
+            username = CharField(max_length=10, initial='djangonaut')
  1160
+            password = CharField(widget=PasswordInput)
  1161
+
  1162
+        unbound = UserRegistration()
  1163
+        bound = UserRegistration({'password': 'foo'})
  1164
+        self.assertEqual(bound['username'].value(), None)
  1165
+        self.assertEqual(unbound['username'].value(), 'djangonaut')
  1166
+        self.assertEqual(bound['password'].value(), 'foo')
  1167
+        self.assertEqual(unbound['password'].value(), None)
  1168
+
1154 1169
     def test_help_text(self):
1155 1170
         # You can specify descriptive text for a field by using the 'help_text' argument)
1156 1171
         class UserRegistration(Form):

0 notes on commit d3f5f21

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