#18709 closed Bug (fixed)
Formset with SplitDateTimeField(initial=datetime.datetime.now) doesn't work correctly
Reported by: | Jeroen Dekkers | Owned by: | |
---|---|---|---|
Component: | Forms | Version: | 1.4 |
Severity: | Normal | Keywords: | |
Cc: | jason@… | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The following code doesn't work (it's included as a test case in the patch):
class SplitDateTimeForm(forms.Form): when = forms.SplitDateTimeField(initial=datetime.datetime.now) SplitDateTimeFormSet = forms.formsets.formset_factory(SplitDateTimeForm) data = { 'form-TOTAL_FORMS': '1', 'form-INITIAL_FORMS': '0', 'form-0-when_0': '1904-06-16', 'form-0-when_1': '15:51:33', } formset = SplitDateTimeFormSet(data) formset.is_valid()
It gives the following stack trace:
Traceback (most recent call last): File "/home/jeroen/github/django/tests/regressiontests/forms/tests/formsets.py", line 870, in test_formset_splitdatetimefield self.assertTrue(formset.is_valid()) File "/home/jeroen/github/django/django/forms/formsets.py", line 271, in is_valid err = self.errors File "/home/jeroen/github/django/django/forms/formsets.py", line 249, in _get_errors self.full_clean() File "/home/jeroen/github/django/django/forms/formsets.py", line 292, in full_clean self._errors.append(form.errors) File "/home/jeroen/github/django/django/forms/forms.py", line 116, in _get_errors self.full_clean() File "/home/jeroen/github/django/django/forms/forms.py", line 269, in full_clean if self.empty_permitted and not self.has_changed(): File "/home/jeroen/github/django/django/forms/forms.py", line 324, in has_changed return bool(self.changed_data) File "/home/jeroen/github/django/django/forms/forms.py", line 347, in _get_changed_data if field.widget._has_changed(initial_value, data_value): File "/home/jeroen/github/django/django/forms/widgets.py", line 847, in _has_changed initial = self.decompress(initial) File "/home/jeroen/github/django/django/forms/widgets.py", line 897, in decompress return [value.date(), value.time().replace(microsecond=0)] AttributeError: 'builtin_function_or_method' object has no attribute 'date'
The problem is that _get_changed_data doesn't check whether initial is a callable and calls the _has_changed widget method with the callable as initial_value. Because the default _has_changed does a force_unicode before comparing, we never get an error for the simple widgets as force_unicode simply returns
u'<built-in method now of type object at 0x7f77b3be7c40>', so it just always returns True for such fields. Any widget that does something more with initial_value will fail however.
The patch fixes _get_changed_data to call the initial value when it is a callable.
Change History (10)
comment:1 by , 12 years ago
comment:2 by , 12 years ago
Cc: | added |
---|---|
Owner: | changed from | to
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
Patch applies cleanly. Test fails before applying patch. Test passes after patch.
comment:3 by , 12 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
comment:4 by , 12 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
comment:5 by , 11 years ago
It will be very nice to merge because it is breaking pull request for ticket #19019
comment:6 by , 11 years ago
The patch looks good, but unfortunately it doesn't apply cleanly any longer.
If you bring it up to date, you can mark it as ready for checkin.
comment:7 by , 11 years ago
Triage Stage: | Ready for checkin → Accepted |
---|
comment:8 by , 11 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
I've rebased the commit so it applies again.
comment:9 by , 11 years ago
Owner: | set to |
---|---|
Resolution: | → fixed |
Status: | new → closed |
https://github.com/django/django/pull/246