summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2007-05-12 15:50:32 +0000
committerRussell Keith-Magee <russell@keith-magee.com>2007-05-12 15:50:32 +0000
commit2345029d0d607ebeea7e7a6e1bff6c09eaaff4a8 (patch)
tree9a648fecf5336bbc7c6813ced2beafea7242e26f
parent330cc98c7381f44b3d1fbf81a3988515bc61d120 (diff)
Fixed #4018 -- Added code to allow callables as initial data in newforms. Thanks for the patch, David Danier.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5209 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--AUTHORS1
-rw-r--r--django/newforms/forms.py2
-rw-r--r--tests/regressiontests/forms/tests.py58
3 files changed, 61 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
index 855717ea64..2352875027 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -78,6 +78,7 @@ answer newbie questions, and generally made Django that much better:
flavio.curella@gmail.com
Jure Cuhalev <gandalf@owca.info>
dackze+django@gmail.com
+ David Danier <goliath.mailinglist@gmx.de>
Dirk Datzert <dummy@habmalnefrage.de>
Jonathan Daugherty (cygnus) <http://www.cprogrammer.org/>
dave@thebarproject.com
diff --git a/django/newforms/forms.py b/django/newforms/forms.py
index 9fafd20787..edd1992cf4 100644
--- a/django/newforms/forms.py
+++ b/django/newforms/forms.py
@@ -255,6 +255,8 @@ class BoundField(StrAndUnicode):
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
return widget.render(self.html_name, data, attrs=attrs)
diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py
index 0d3a65277c..d6b08a0cd3 100644
--- a/tests/regressiontests/forms/tests.py
+++ b/tests/regressiontests/forms/tests.py
@@ -2752,6 +2752,64 @@ then the latter will get precedence.
<li>Username: <input type="text" name="username" value="babik" maxlength="10" /></li>
<li>Password: <input type="password" name="password" /></li>
+# Callable initial data ########################################################
+
+The previous technique dealt with raw values as initial data, but it's also
+possible to specify callable data.
+
+>>> class UserRegistration(Form):
+... username = CharField(max_length=10)
+... password = CharField(widget=PasswordInput)
+
+We need to define functions that get called later.
+>>> def initial_django():
+... return 'django'
+>>> def initial_stephane():
+... return 'stephane'
+
+Here, we're not submitting any data, so the initial value will be displayed.
+>>> p = UserRegistration(initial={'username': initial_django}, auto_id=False)
+>>> print p.as_ul()
+<li>Username: <input type="text" name="username" value="django" maxlength="10" /></li>
+<li>Password: <input type="password" name="password" /></li>
+
+The 'initial' parameter is meaningless if you pass data.
+>>> p = UserRegistration({}, initial={'username': initial_django}, auto_id=False)
+>>> print p.as_ul()
+<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
+<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
+>>> p = UserRegistration({'username': u''}, initial={'username': initial_django}, auto_id=False)
+>>> print p.as_ul()
+<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
+<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
+>>> p = UserRegistration({'username': u'foo'}, initial={'username': initial_django}, auto_id=False)
+>>> print p.as_ul()
+<li>Username: <input type="text" name="username" value="foo" maxlength="10" /></li>
+<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
+
+A callable 'initial' value is *not* used as a fallback if data is not provided.
+In this example, we don't provide a value for 'username', and the form raises a
+validation error rather than using the initial value for 'username'.
+>>> p = UserRegistration({'password': 'secret'}, initial={'username': initial_django})
+>>> p.errors
+{'username': [u'This field is required.']}
+>>> p.is_valid()
+False
+
+If a Form defines 'initial' *and* 'initial' is passed as a parameter to Form(),
+then the latter will get precedence.
+>>> class UserRegistration(Form):
+... username = CharField(max_length=10, initial=initial_django)
+... password = CharField(widget=PasswordInput)
+>>> p = UserRegistration(auto_id=False)
+>>> print p.as_ul()
+<li>Username: <input type="text" name="username" value="django" maxlength="10" /></li>
+<li>Password: <input type="password" name="password" /></li>
+>>> p = UserRegistration(initial={'username': initial_stephane}, auto_id=False)
+>>> print p.as_ul()
+<li>Username: <input type="text" name="username" value="stephane" maxlength="10" /></li>
+<li>Password: <input type="password" name="password" /></li>
+
# Help text ###################################################################
You can specify descriptive text for a field by using the 'help_text' argument