﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
18709	Formset with SplitDateTimeField(initial=datetime.datetime.now) doesn't work correctly	Jeroen Dekkers	Jeroen Dekkers <jeroen@…>	"The following code doesn't work (it's included as a test case in the patch):

{{{
#!python
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:

{{{
#!python
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."	Bug	closed	Forms	1.4	Normal	fixed		jason@…	Ready for checkin	1	0	0	0	0	0
