Index: django/forms/forms.py
===================================================================
--- django/forms/forms.py	(revision 9984)
+++ django/forms/forms.py	(working copy)
@@ -366,17 +366,11 @@
         auto_id = self.auto_id
         if auto_id and 'id' not in attrs and 'id' not in widget.attrs:
             attrs['id'] = auto_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.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):
         """
@@ -401,6 +395,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, as rendered in widgets.
+        """
+        if not self.form.is_bound:
+            val = self.form.initial.get(self.name, self.field.initial)
+            if callable(val):
+                val = val()
+        else:
+            val = self.data
+        if val is None:
+            val = ''
+        return val
+    value = property(_value)
+
     def label_tag(self, contents=None, attrs=None):
         """
         Wraps the given contents in a <label>, if the field has an ID attribute.
Index: tests/regressiontests/forms/forms.py
===================================================================
--- tests/regressiontests/forms/forms.py	(revision 9984)
+++ tests/regressiontests/forms/forms.py	(working copy)
@@ -1196,6 +1196,31 @@
 <li>Username: <input type="text" name="username" value="stephane" maxlength="10" /></li>
 <li>Password: <input type="password" name="password" /></li>
 
+# Bound field values ##########################################################
+
+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 attribute.
+
+>>> class UserRegistration(Form):
+...    username = CharField(max_length=10, initial='djangonaut')
+...    password = CharField(widget=PasswordInput)
+>>> p = UserRegistration({'password': 'foo'})
+>>> print 'username.value =', p['username'].value
+username.value = 
+>>> print 'username.data = ', p['username'].data
+username.data = None
+>>> print 'password.value =', p['password'].value
+password.value = foo
+>>> print 'password.data =', p['password'].data
+password.data = foo
+
+The value of username is empty because the form is bound -- the value wasn't
+specified, and so is empty. This differs if the form were to be unbound:
+
+>>> p = UserRegistration()
+>>> print p['username'].value
+djangonaut
+
 # Help text ###################################################################
 
 You can specify descriptive text for a field by using the 'help_text' argument
Index: docs/ref/forms/fields.txt
===================================================================
--- docs/ref/forms/fields.txt	(revision 9984)
+++ docs/ref/forms/fields.txt	(working copy)
@@ -293,7 +293,37 @@
     <tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
     <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
 
+Field data versus value
+~~~~~~~~~~~~~~~~~~~~~~~
 
+.. versionadded:: 1.1
+
+.. attribute:: Field.value
+.. attribute:: Field.data
+
+Sometimes, it's necessary -- or at least easier -- to render the form entirely
+on your own. In such a case, you might want to get to what Django's form
+rendering would use for the HTML `value` attribute.
+
+It's quite easy, actually::
+
+    >>> f = CommentForm({'comment': 'Foobar'}, initial={'name': 'instance'})
+    >>> f['name'].value
+    'instance'
+    >>> f['comment'].value
+    'Foobar'
+
+The value attribute takes initial data into account on form level (i.e.,
+passing it to the initializer as seen in previous section), as well as field
+level.
+
+The resolution process is, step by step, the following:
+
+ 1. If the form has data for this field, use it;
+ 2. if the form has initial data for this field, use it;
+ 3. if the field has initial data, use it; and lastly
+ 4. use the empty string.
+
 Built-in ``Field`` classes
 --------------------------
 
