Search code examples
pythonpostflaskradio-buttondefault-value

Python Flask: Bad Request on Post method with radio-option checked


Lets say I have 2 radio buttons in my html script, of which one is checked by default:

<form action="" method="post">
    <div class="radio-option checked">
        <input type="radio" name="radioName" value="val_1"/>
    </div>
    <div class="radio-option">
        <input type="radio" name="radioName" value="val_2"/>
    </div>
    <div>
        <input type="submit" value="Confirm and continue"/>
    </div>
</form>

If I click the submit button without clicking the other radio button, I get an error:

Bad Request The browser (or proxy) sent a request that this server could not understand.

This happens because there is no value which is being transfered if a radio button is checked by default but not being selected with the mouse afterwards! This is what request.form shows me ImmutableMultiDict([]). If I select the other radio button with the mouse and click the submit button it shows me values ImmutableMultiDict(['radioName', 'val_2'])

I tried to catch the error like this, but it didn't work out:

if request.form == '':
    flash('error')
    return render_template('default_template.html')
  1. How can I handle this within flask?
  2. How can I set a default value, which can be sent to the server?

Solution

  • You could perform a check within flask. Check if request.form has items or if its empty and throw the error in that case. A simple way of knowing if its empty would be, for example:

    if len(request.form) == 0:
        print('Error: The form is empty')
    else:
        print('The form has data, we can proceed')
    

    Another way is:

    if 'radioName' not in request.form:
        print('Error: The form is empty')
        ...
    

    But maybe flask has a better way of doing this or there are better practices to follow in these cases.

    On the other hand, in the html snippet that you posted, none of the inputs is checked by default. You have the checked css class on a div but not the checked attribute in an input with type=radio.

    The correct use of checked attribute would be as follows:

    <form action="" method="post">
        <div class="radio-option checked">
            <input type="radio" name="radioName" value="val_1" checked/>
        </div>
        <div class="radio-option">
            <input type="radio" name="radioName" value="val_2"/>
        </div>
        <div>
            <input type="submit" value="Confirm and continue"/>
        </div>
    </form>
    

    This way, the radio input with value val_1, will be checked by default, populating the dictionary that goes to the server.

    For more information, check out: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio

    You can also avoid sending empty forms to the server using the required attribute to make sure that the user fills the form as expected.

    To learn more about this: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation

    I hope it helps!