Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #11940 - ModelForm evaluates callable default values on form cl…

…ass creation

Thanks to Harm Geerts for the report and initial patch.



git-svn-id: http://code.djangoproject.com/svn/django/trunk@12721 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit bae921dcff699b827cd423f01ed125221b32fc9a 1 parent 5e3a2e2
@spookylukey spookylukey authored
View
4 django/db/models/fields/__init__.py
@@ -445,9 +445,11 @@ def formfield(self, form_class=forms.CharField, **kwargs):
"Returns a django.forms.Field instance for this database Field."
defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text}
if self.has_default():
- defaults['initial'] = self.get_default()
if callable(self.default):
+ defaults['initial'] = self.default
defaults['show_hidden_initial'] = True
+ else:
+ defaults['initial'] = self.get_default()
if self.choices:
# Fields with choices get special treatment.
include_blank = self.blank or not (self.has_default() or 'initial' in kwargs)
View
2  tests/modeltests/model_formsets/models.py
@@ -959,7 +959,7 @@ def __unicode__(self):
# when determine what extra forms have changed to save.
>>> form = formset.forms[0] # this formset only has one form
->>> now = form.fields['date_joined'].initial
+>>> now = form.fields['date_joined'].initial()
>>> print form.as_p()
<p><label for="id_membership_set-0-date_joined">Date joined:</label> <input type="text" name="membership_set-0-date_joined" value="..." id="id_membership_set-0-date_joined" /><input type="hidden" name="initial-membership_set-0-date_joined" value="..." id="initial-membership_set-0-id_membership_set-0-date_joined" /></p>
<p><label for="id_membership_set-0-karma">Karma:</label> <input type="text" name="membership_set-0-karma" id="id_membership_set-0-karma" /><input type="hidden" name="membership_set-0-person" value="1" id="id_membership_set-0-person" /><input type="hidden" name="membership_set-0-id" id="id_membership_set-0-id" /></p>
View
13 tests/regressiontests/forms/models.py
@@ -17,10 +17,17 @@
class BoundaryModel(models.Model):
positive_integer = models.PositiveIntegerField(null=True, blank=True)
+callable_default_value = 0
+def callable_default():
+ global callable_default_value
+ callable_default_value = callable_default_value + 1
+ return callable_default_value
+
class Defaults(models.Model):
name = models.CharField(max_length=255, default='class default value')
def_date = models.DateField(default = datetime.date(1980, 1, 1))
value = models.IntegerField(default=42)
+ callable_default = models.IntegerField(default=callable_default)
class ChoiceModel(models.Model):
"""For ModelChoiceField and ModelMultipleChoiceField tests."""
@@ -112,6 +119,10 @@ def test_choices_not_fetched_when_not_rendering(self):
datetime.date(1980, 1, 1)
>>> DefaultsForm().fields['value'].initial
42
+>>> r1 = DefaultsForm()['callable_default'].as_widget()
+>>> r2 = DefaultsForm()['callable_default'].as_widget()
+>>> r1 == r2
+False
In a ModelForm that is passed an instance, the initial values come from the
instance's values, not the model's defaults.
@@ -129,7 +140,7 @@ def test_choices_not_fetched_when_not_rendering(self):
... name = CharField(max_length=255)
... class Meta:
... model = Defaults
-... exclude = ['name']
+... exclude = ['name', 'callable_default']
>>> f = ExcludingForm({'name': u'Hello', 'value': 99, 'def_date': datetime.date(1999, 3, 2)})
>>> f.is_valid()
True
Please sign in to comment.
Something went wrong with that request. Please try again.