﻿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
12858	Callable default on DateField + custom date format = widget._has_changed always true, forms fail to validate	Daniel Marohn	nobody	"I have a {{{ModelFormset}}} with some extra forms. The model the forms are based on contains a {{{DateField}}} with {{{default=datetime.date.today}}}, and other fields which are required. It must be possible to submit the formset without filling in all extra forms (which wouldn't validate when empty, due to the fact that there are required fields), so the formset sets {{{empty_permitted}}} on the extra forms: this lets those forms skip validation as long as their fields have not changed ({{{if self.empty_permitted and not self.has_changed())}}} in {{{BaseForm.full_clean}}}. So far this is all standard formset behaviour.

I need to render the dates in a custom (ie local) format, so I have an {{{__init__}}} method on my modelform which replaces the widgets of {{{DateField}}}s with a {{{DateInput}}} created with the desired format. This is also rather standard widget customization.

However, this causes Django to incorrectly treat every instance of the form as changed. The problem stems from the fact that Django compares the current data and the initial data in string form. Since the model {{{DateField}}} has a callable default, it generates a form field with {{{show_hidden_initial}}} set to True; this causes the form to store the initial value in a separate hidden widget, created by calling hidden_widget on the field. This corresponds to the {{{HiddenInput}}} class for most formfields, including {{{DateField}}}. When {{{HiddenInput}}} renders, it formats the date using the default ISO format instead of the custom format used by the corresponding {{{DateInput}}}. Therefore, {{{DateInput._has_changed}}} sees two different strings (eg 2010-02-13 vs 13/02/2010), and thinks the field has changed even when it has not. In some cases, it may also think it has not changed when it has: for example, when one format is D/M/Y and the other is M/D/Y, and the user happens to change the date from Feb. 1 to Jan. 2 (01/02/2010 vs 01/02/2010).

The patch fixes this problem by having {{{DateInput._has_changed}}} attempt to parse the initial value using the same format used by the {{{HiddenInput}}}. If the initial value was a string, and was in that format, then it is converted to a date object, which is later converted back into a string using the {{{DateInput}}}'s own format; otherwise, everything remains as before."		closed	Forms	dev		fixed	dateinput format		Accepted	1	0	1	0	0	0
