#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 Changed 7 years ago by
comment:2 Changed 7 years ago by
Cc: | jason@… added |
---|---|
Owner: | changed from nobody to Jason Mayfield |
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
Patch applies cleanly. Test fails before applying patch. Test passes after patch.
comment:3 Changed 7 years ago by
Triage Stage: | Accepted → Ready for checkin |
---|
comment:4 Changed 7 years ago by
Owner: | Jason Mayfield deleted |
---|---|
Status: | assigned → new |
comment:5 Changed 7 years ago by
It will be very nice to merge because it is breaking pull request for ticket #19019
comment:6 Changed 7 years ago by
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 Changed 7 years ago by
Triage Stage: | Ready for checkin → Accepted |
---|
comment:8 Changed 7 years ago by
Triage Stage: | Accepted → Ready for checkin |
---|
I've rebased the commit so it applies again.
comment:9 Changed 7 years ago by
Owner: | set to Jeroen Dekkers <jeroen@…> |
---|---|
Resolution: | → fixed |
Status: | new → closed |
https://github.com/django/django/pull/246