+# 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 10650)
+++ docs/ref/forms/fields.txt (working copy)
@@ -257,6 +257,37 @@
In the `built-in Field classes`_ section below, each ``Field`` defines the
error message keys it uses.
+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
--------------------------
Index: django/forms/forms.py
===================================================================
--- django/forms/forms.py (revision 10650)
+++ django/forms/forms.py (working copy)
@@ -375,20 +375,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:
- if isinstance(self.field, FileField) and self.data is None:
- data = self.form.initial.get(self.name, self.field.initial)
- 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):
"""
@@ -413,6 +404,24 @@
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:
+ if isinstance(self.field, FileField) and self.data is None:
+ val = self.form.initial.get(self.name, self.field.initial)
+ 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