Author: SmileyChris
Date: 2010-11-27 20:50:31 -0600 (Sat, 27 Nov 2010)
New Revision: 14734

Modified:
   django/trunk/django/forms/forms.py
   django/trunk/docs/ref/forms/api.txt
   django/trunk/tests/regressiontests/forms/tests/forms.py
Log:
Fixes #10427 -- Abstract the value generation of a BoundField

Modified: django/trunk/django/forms/forms.py
===================================================================
--- django/trunk/django/forms/forms.py  2010-11-27 22:43:33 UTC (rev 14733)
+++ django/trunk/django/forms/forms.py  2010-11-28 02:50:31 UTC (rev 14734)
@@ -432,20 +432,11 @@
             else:
                 attrs['id'] = self.html_initial_id
 
-        if not self.form.is_bound:
-            data = self.form.initial.get(self.name, self.field.initial)
-            if callable(data):
-                data = data()
-        else:
-            data = self.field.bound_data(
-                self.data, self.form.initial.get(self.name, 
self.field.initial))
-        data = self.field.prepare_value(data)
-
         if not only_initial:
             name = self.html_name
         else:
             name = self.html_initial_name
-        return widget.render(name, data, attrs=attrs)
+        return widget.render(name, self.value(), attrs=attrs)
 
     def as_text(self, attrs=None, **kwargs):
         """
@@ -470,6 +461,21 @@
         return self.field.widget.value_from_datadict(self.form.data, 
self.form.files, self.html_name)
     data = property(_data)
 
+    def value(self):
+        """
+        Returns the value for this BoundField, using the initial value if
+        the form is not bound or the data otherwise.
+        """
+        if not self.form.is_bound:
+            data = self.form.initial.get(self.name, self.field.initial)
+            if callable(data):
+                data = data()
+        else:
+            data = self.field.bound_data(
+                self.data, self.form.initial.get(self.name, self.field.initial)
+            )
+        return self.field.prepare_value(data)
+
     def label_tag(self, contents=None, attrs=None):
         """
         Wraps the given contents in a <label>, if the field has an ID 
attribute.

Modified: django/trunk/docs/ref/forms/api.txt
===================================================================
--- django/trunk/docs/ref/forms/api.txt 2010-11-27 22:43:33 UTC (rev 14733)
+++ django/trunk/docs/ref/forms/api.txt 2010-11-28 02:50:31 UTC (rev 14734)
@@ -584,36 +584,29 @@
 The ``as_p()``, ``as_ul()`` and ``as_table()`` methods are simply shortcuts for
 lazy developers -- they're not the only way a form object can be displayed.
 
-To display the HTML for a single field in your form, use dictionary lookup
-syntax using the field's name as the key, and print the resulting object::
+.. class:: BoundField
 
-    >>> f = ContactForm()
-    >>> print f['subject']
-    <input id="id_subject" type="text" name="subject" maxlength="100" />
-    >>> print f['message']
-    <input type="text" name="message" id="id_message" />
-    >>> print f['sender']
-    <input type="text" name="sender" id="id_sender" />
-    >>> print f['cc_myself']
-    <input type="checkbox" name="cc_myself" id="id_cc_myself" />
+   Used to display HTML or access attributes for a single field of a
+   :class:`Form` instance.
+   
+   The :meth:`__unicode__` and :meth:`__str__` methods of this object displays
+   the HTML for this field.
 
-Call ``str()`` or ``unicode()`` on the field to get its rendered HTML as a
-string or Unicode object, respectively::
+To retrieve a single ``BoundField``, use dictionary lookup syntax on your form
+using the field's name as the key::
 
-    >>> str(f['subject'])
-    '<input id="id_subject" type="text" name="subject" maxlength="100" />'
-    >>> unicode(f['subject'])
-    u'<input id="id_subject" type="text" name="subject" maxlength="100" />'
+       >>> form = ContactForm()
+       >>> print form['subject']
+       <input id="id_subject" type="text" name="subject" maxlength="100" />
 
-Form objects define a custom ``__iter__()`` method, which allows you to loop
-through their fields::
+To retrieve all ``BoundField`` objects, iterate the form::
 
-    >>> f = ContactForm()
-    >>> for field in f: print field
-    <input id="id_subject" type="text" name="subject" maxlength="100" />
-    <input type="text" name="message" id="id_message" />
-    <input type="text" name="sender" id="id_sender" />
-    <input type="checkbox" name="cc_myself" id="id_cc_myself" />
+       >>> form = ContactForm()
+       >>> for boundfield in form: print boundfield
+       <input id="id_subject" type="text" name="subject" maxlength="100" />
+       <input type="text" name="message" id="id_message" />
+       <input type="text" name="sender" id="id_sender" />
+       <input type="checkbox" name="cc_myself" id="id_cc_myself" />
 
 The field-specific output honors the form object's ``auto_id`` setting::
 
@@ -624,27 +617,32 @@
     >>> print f['message']
     <input type="text" name="message" id="id_message" />
 
-For a field's list of errors, access the field's ``errors`` attribute. This
-is a list-like object that is displayed as an HTML ``<ul class="errorlist">``
-when printed::
+For a field's list of errors, access the field's ``errors`` attribute.
 
-    >>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''}
-    >>> f = ContactForm(data, auto_id=False)
-    >>> print f['message']
-    <input type="text" name="message" />
-    >>> f['message'].errors
-    [u'This field is required.']
-    >>> print f['message'].errors
-    <ul class="errorlist"><li>This field is required.</li></ul>
-    >>> f['subject'].errors
-    []
-    >>> print f['subject'].errors
+.. attribute:: BoundField.errors
 
-    >>> str(f['subject'].errors)
-    ''
+    A list-like object that is displayed as an HTML ``<ul class="errorlist">``
+    when printed::
 
-.. versionadded:: 1.2
+        >>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': 
''}
+        >>> f = ContactForm(data, auto_id=False)
+        >>> print f['message']
+        <input type="text" name="message" />
+        >>> f['message'].errors
+        [u'This field is required.']
+        >>> print f['message'].errors
+        <ul class="errorlist"><li>This field is required.</li></ul>
+        >>> f['subject'].errors
+        []
+        >>> print f['subject'].errors
 
+        >>> str(f['subject'].errors)
+           ''
+
+.. method:: BoundField.css_classes()
+
+   .. versionadded:: 1.2
+
 When you use Django's rendering shortcuts, CSS classes are used to
 indicate required form fields or fields that contain errors. If you're
 manually rendering a form, you can access these CSS classes using the
@@ -662,6 +660,21 @@
        >>> f['message'].css_classes('foo bar')
        'foo bar required'
 
+.. method:: BoundField.values()
+
+   .. versionadded:: 1.3
+
+Use this method to render the raw value of this field as it would be rendered
+by a ``Widget``::
+
+    >>> initial = {'subject': 'welcome'}
+    >>> unbound_form = ContactForm(initial=initial)
+    >>> bound_form = ContactForm(data, initial=initial)
+    >>> print unbound_form['subject'].value
+    welcome
+    >>> print bound_form['subject'].value
+    hi
+
 .. _binding-uploaded-files:
 
 Binding uploaded files to a form

Modified: django/trunk/tests/regressiontests/forms/tests/forms.py
===================================================================
--- django/trunk/tests/regressiontests/forms/tests/forms.py     2010-11-27 
22:43:33 UTC (rev 14733)
+++ django/trunk/tests/regressiontests/forms/tests/forms.py     2010-11-28 
02:50:31 UTC (rev 14734)
@@ -1151,6 +1151,21 @@
 <option value="w">whiz</option>
 </select></li>""")
 
+    def test_boundfield_values(self):
+        # It's possible to get to the value which would be used for rendering
+        # the widget for a field by using the BoundField's value method.
+ 
+        class UserRegistration(Form):
+            username = CharField(max_length=10, initial='djangonaut')
+            password = CharField(widget=PasswordInput)
+
+        unbound = UserRegistration()
+        bound = UserRegistration({'password': 'foo'})
+        self.assertEqual(bound['username'].value(), None)
+        self.assertEqual(unbound['username'].value(), 'djangonaut')
+        self.assertEqual(bound['password'].value(), 'foo')
+        self.assertEqual(unbound['password'].value(), None)
+
     def test_help_text(self):
         # You can specify descriptive text for a field by using the 
'help_text' argument)
         class UserRegistration(Form):

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to