Opened 2 years ago

Closed 2 years ago

Last modified 4 months ago

#22406 closed Bug (needsinfo)

Inconsistent way to parse boolean value from posted data

Reported by: xiaowl@… Owned by: nobody
Component: Forms Version: 1.6
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

django.forms.fields.BooleanField.to_python tries to test if the given value is in ('false', '0'), but the value passed in is collected via BooleanField.widget.value_from_datadict, which uses a predefined dict {'true': True, 'false': False} to retreive boolean value, otherwise it returns bool(value).

Thus, posting a boolean field with value '0' will produce True, instead of False.


Attachments (1)

patch.diff (135 bytes) - added by xiaowl@… 2 years ago.

Download all attachments as: .zip

Change History (3)

Changed 2 years ago by xiaowl@…

Attachment: patch.diff added

comment:1 Changed 2 years ago by Claude Paroz

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
Resolution: needsinfo
Status: newclosed

The fact that CheckboxInput.value_from_datadict treats 0 as True is by design (see #16820).
Please provide us with a more detailed use case to show why the above behavior is problematic for you.

comment:2 Changed 4 months ago by Ciro Santilli 六四事件 法轮功 包卓轩

I am doing something like this:

  • a single AJAX view creates or deletes user up or down votes for posts. If the vote already exists, it is deleted or modified.
  • there are two types of vote differentiated by a Booleanfield (application specific, difficult to explain), let's call them typeTrue and typeFalse
  • each user can do a single vote of each type (typeTrue and typeFalse) either up or down

Now the view works as follows:

  • check if the vote of a given type already exists for a given user. This is an unique triple. This step runs: Vote.filter(booleanfield=request.POST['booleanfield'])
  • if the exact same vote exists, delete it
  • if it exists but with a different value (up or down vote), get the existing vote vote, and update it. This means a form validation: form = Vote(request.POST, instance=vote)

So now, what should my AJAX send?

If nothing, as a form submission checkbox would on False, the existing vote is not found as it should to be deleted.

If '0', the form always gives me True.

I think 'false' would work because it works for both, but it feels inconsistent. Why '0' does not work as well?

Actual code: https://github.com/cirosantilli/free-books-django-raw/blob/d4cb03d61a6f0c19ac7333ee1099e679e0acef21/free_books/views.py#L280

Last edited 4 months ago by Ciro Santilli 六四事件 法轮功 包卓轩 (previous) (diff)
Note: See TracTickets for help on using tickets.
Back to Top