Opened 8 years ago

Closed 7 years ago

Last modified 7 years ago

#18709 closed Bug (fixed)

Formset with SplitDateTimeField( doesn't work correctly

Reported by: Jeroen Dekkers Owned by: Jeroen Dekkers <jeroen@…>
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


The following code doesn't work (it's included as a test case in the patch):

class SplitDateTimeForm(forms.Form):
    when = forms.SplitDateTimeField(

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)

It gives the following stack trace:

Traceback (most recent call last):
  File "/home/jeroen/github/django/tests/regressiontests/forms/tests/", line 870, in test_formset_splitdatetimefield
  File "/home/jeroen/github/django/django/forms/", line 271, in is_valid
    err = self.errors
  File "/home/jeroen/github/django/django/forms/", line 249, in _get_errors
  File "/home/jeroen/github/django/django/forms/", line 292, in full_clean
  File "/home/jeroen/github/django/django/forms/", line 116, in _get_errors
  File "/home/jeroen/github/django/django/forms/", line 269, in full_clean
    if self.empty_permitted and not self.has_changed():
  File "/home/jeroen/github/django/django/forms/", line 324, in has_changed
    return bool(self.changed_data)
  File "/home/jeroen/github/django/django/forms/", line 347, in _get_changed_data
    if field.widget._has_changed(initial_value, data_value):
  File "/home/jeroen/github/django/django/forms/", line 847, in _has_changed
    initial = self.decompress(initial)
  File "/home/jeroen/github/django/django/forms/", line 897, in decompress
    return [, 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:2 Changed 8 years ago by Jason Mayfield

Cc: jason@… added
Owner: changed from nobody to Jason Mayfield
Status: newassigned
Triage Stage: UnreviewedAccepted

Patch applies cleanly. Test fails before applying patch. Test passes after patch.

comment:3 Changed 8 years ago by Jason Mayfield

Triage Stage: AcceptedReady for checkin

comment:4 Changed 8 years ago by Jason Mayfield

Owner: Jason Mayfield deleted
Status: assignednew

comment:5 Changed 7 years ago by Kamil Gałuszka

It will be very nice to merge because it is breaking pull request for ticket #19019

comment:6 Changed 7 years ago by Aymeric Augustin

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 Aymeric Augustin

Triage Stage: Ready for checkinAccepted

comment:8 Changed 7 years ago by Jeroen Dekkers

Triage Stage: AcceptedReady for checkin

I've rebased the commit so it applies again.

comment:9 Changed 7 years ago by Jeroen Dekkers <jeroen@…>

Owner: set to Jeroen Dekkers <jeroen@…>
Resolution: fixed
Status: newclosed

In d0788c277035727b7b070abd0f02d075acffc84f:

Fixed #18709 -- Check if initial_value is a callable

In _get_changed_data, check if initial_value is a callable and call it
if it is.

comment:10 Changed 7 years ago by Marc Tamlyn <marc.tamlyn@…>

In adeec00979d1b365535b8f26fda4a5f7173e975d:

Merge pull request #246 from dekkers/ticket_18709

Fixed #18709 -- Check if initial_value is a callable

Note: See TracTickets for help on using tickets.
Back to Top