#19537 closed Bug (fixed)
Widget CheckboxInput show_hidden_initial _has_changed bug
Reported by: | Owned by: | Claude Paroz | |
---|---|---|---|
Component: | Forms | Version: | 1.4 |
Severity: | Normal | Keywords: | show_hidden_initial |
Cc: | 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 (last modified by )
django.forms.CheckboxInput
have method
def _has_changed(self, initial, data): # Sometimes data or initial could be None or u'' which should be the # same thing as False. return bool(initial) != bool(data)
initial may be u'False' or u'True'
bool(initial) always return True for unicode len(initial) > 1
if initial == u'False' and data == u'on' always return False
bool(u'False') = True
bool(u'on') = True
path:
def _has_changed(self, initial, data): initial = True if initial == u'True' else False return initial != bool(data)
Attachments (1)
Change History (11)
comment:1 by , 12 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 12 years ago
my initial data is bool type
ok full test case is
# View is
def document(request, project_id, document_id): u''' Карточка документа ''' class TestForm(forms.Form): bool_field = forms.BooleanField(show_hidden_initial=True, required=False) if request.method == 'POST': f = TestForm(data=request.POST) if f.is_valid(): print f.changed_data else: # initial is bool type not unicode! f = TestForm(initial={u'bool_field':False}) return render(request, 'docflow/document.html', {'form':f})
# Template is
<html> <body> <form method='post'> {% csrf_token %} {{form.as_p}} <input type='submit'> </form> </body> </html>
# action1
- load page
- checkbox is not cheched by default
- check checkbox and send form (change!)
- print to console is "[]"
CheckboxInput._has_changed arg "initial" == u'False' (not bool False) bool(u'False') == True of course,
but arg "data" == u'on' bool(u'on') == True too
True != True => False
# action2
- load page
- checkbox is not cheched by default
- send form
- print to console is "bool_field"
CheckboxInput._has_changed arg "initial" == u'False' too bool(u'False') => True,
but arg "data" == False bool(False) == False
widget _has_changed => true
comment:3 by , 12 years ago
Component: | Uncategorized → Forms |
---|---|
Resolution: | invalid |
Status: | closed → new |
reopen tiket
comment:4 by , 12 years ago
Description: | modified (diff) |
---|
by , 12 years ago
Attachment: | 19537-1.diff added |
---|
comment:5 by , 12 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
Sorry, I didn't get it at first, thanks for giving more details. Please review the attached patch.
comment:6 by , 12 years ago
Checkbox patch is great!
but DateField is too
i set
- DATE_INPUT_FORMATS = ('%d.%m.%Y',)
- input_formats=('%d.%m.%Y',) in field
- format='%d.%m.%Y' in widget
:-)
but hidden initial input value is u'2012-12-13' (not 13.12.2012)
in django.forms.DateInput._has_changed
# If our field has show_hidden_initial=True, initial will be a string # formatted by HiddenInput using formats.localize_input, which is not # necessarily the format used for this widget. Attempt to convert it. try: input_format = formats.get_format('DATE_INPUT_FORMATS')[0] initial = datetime.datetime.strptime(initial, input_format).date() except (TypeError, ValueError): pass return super(DateInput, self)._has_changed(self._format_value(initial), data)
step by step in function
- formats.get_format('DATE_INPUT_FORMATS')[0] return %d.%m.%Y
but is not work for initial hidden value u'2012-12-13'
Exception pass
and initial stay u'2012-12-13'
- datetime.datetime.strptime(initial, input_format).date() fails
and initial stay u'2012-12-13'
- self._format_value(initial) return initial
self.manual_format = True
value not has attr strftime (value is unicode)
and initial stay u'2012-12-13'
- super(DateInput, self)._has_changed(u'2012-12-13', u'13.12.2012') return True (as string, initial and data not equal)
problem is format for input hidden initial
comment:7 by , 12 years ago
fix
class DateInput(forms.DateInput): u''' Исправление https://code.djangoproject.com/ticket/19537 ''' def _has_changed(self, initial, data): # if format initial value fixed try: input_format = formats.get_format('DATE_INPUT_FORMATS')[0] initial = datetime.datetime.strptime(initial, input_format).date() except (TypeError, ValueError): pass # if convert Attempt fails, try convert in format '%Y-%m-%d' if type(initial) == unicode: try: initial = datetime.datetime.strptime(initial, '%Y-%m-%d').date() except (TypeError, ValueError): pass return super(DateInput, self)._has_changed(self._format_value(initial), data)
but it's dirty
need to change the format initial input
comment:8 by , 12 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
OK, let's focus on CheckboxInput in this ticket. What you describe has already been reported in #18777. One thing at a time :-)
comment:9 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
By default, any non-empty string is considered as a
True
value, even"False"
. You should fix the initial value passed to the form in your code.