1

I have a Django form with a checkbox = forms.BooleanField(required=False) and in my views I try to get this with:

if request.POST['checkbox'] == True:
    # DO SOMETHING
else:
    # DO SOMETHING ELSE

When the checkbox is selected everything works, but when it isn't it returns the error message MultiValueDictKeyError at /theForm/ and highlights the line with the if statement. It seems if the checkbox doesn't get checked it doesn't return anything even tho the Django Documentation for this element says it should return False.

Normalizes to: A Python True or False value.

How is this done right? I don't want to use a try: except:-function, as this is shouldn't throw an error!

BTW: In the "POST" part of the error message everything else (other data from this form) is mentioned except for the checkbox field.

3
  • Normally in case a checkbox is not selected, it is not in the POST headers. Commented Sep 19, 2018 at 21:12
  • @WillemVanOnsem Like I said in the "BTW" section... But why? And how should I build around this? Are you implying that the Django Documentation is wrong? That it returns nothing if it is not selected? Commented Sep 19, 2018 at 21:15
  • no the documentation is not wrong, but you read it the wrong way :). Django forms are not HTML forms. Django forms are concepts at the server side to generate HTML forms, and parse the data in a HTML form. Commented Sep 19, 2018 at 21:17

1 Answer 1

1

It seems if the checkbox doesn't get checked it doesn't return anything even tho the Django Documentation for this element says it should return False.

That is correct, but here you do not use a Form, you work with the POST data directly. Django's form has not much control about that. Although Django Forms can generate the HTML of a form at client side, these are not that Form. You can see it as a conceptual layer in Django that helps to build forms, as well as parsing the data that comes out of HTTP requests that originate from forms at the client side. But there is some sort of "impedance" between the two.

Normally in case a checkbox is not checked, the name (and value) do not ship with the POST data. This is specified by w3.org as:

Checkboxes (and radio buttons) are on/off switches that may be toggled by the user. A switch is "on" when the control element's checked attribute is set. When a form is submitted, only "on" checkbox controls can become successful.

further in the document, we read:

A successful control is "valid" for submission. Every successful control has its control name paired with its current value as part of the submitted form data set. A successful control must be defined within a FORM element and must have a control name.

So you can perform the check as:

if 'checkbox' in request.POST:
    # DO SOMETHING
else:
    # DO SOMETHING ELSE

Or, a more elegant and failsafe approach is to let the Django form do the work, like:

form = MyForm(request.POST)
if form.is_valid():
    if form.cleaned_data['checkbox']:
        # DO SOMETHING
    else:
        # DO SOMETHING ELSE

There are however situations where the form can be invalid (for example a required field is missing, or some <select> boxes contain invalid data, etc. So you have to find a way to handle such situations as well.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for your quick and detailed response, however unfortunately this doesn't solve my problem. With your first proposed solution the same error comes up and with your second another error (TypeError 'dict' object is not callable) comes up...
Please post the full traceback... (edit the question). I made a typo with the first variant, it should of course be 'checbox' in request.POST
After your edit, it worked! Thank you very much. I think your second solution just doesn't work for me, bc I probably created the form wrong. I will look into this.
Thank you for taking the time to answer the question in such detail! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.