1

I have a simple HTML form that I'm trying to validate with a Django Form. The problem is that Django's form validation will only recognize the value of is_kit if it is 'True'. (When it is 'False', it will give an error saying that the field is required. Here is the form:

<form method="post"> {% csrf_token %}
    <input type="hidden" name="part_id" value="{{ part.id }}" />
    <input type="hidden" name="is_kit" value="False" />
    <input type="submit" class="btn btn-link" value="Add to Cart"/>
</form>

And here is the Django form:

class AddItemToCartForm(forms.Form):
    part_id = forms.IntegerField()
    is_kit = forms.BooleanField()

And here is the relevant part of my view:

def post(self, request, id):
    print(request.POST)
    print(request.POST.get('is_kit'))
    form = AddItemToCartForm(request.POST)
    print(form.errors)

The output my server gives is here:

<QueryDict: {'is_kit': ['False'], 'part_id': ['1'], 'csrfmiddlewaretoken': ['X2vkpwG6GJmK79vypFPAveTzVkrxBauJWgfnRvAtJVcZ8NwBokjQhCnfGN9dFFYF']}>
False
<ul class="errorlist"><li>is_kit<ul class="errorlist"><li>This field is required.</li></ul></li></ul>

I believe that my template should work because looking at the source code, forms.BooleanField should convert the string 'False' in the POST data to a python False value.

As I mentioned above, the form validates perfectly if is_kit is set to 'True'.

Grayson Pike
  • 397
  • 1
  • 4
  • 13

2 Answers2

2

From the doc,

Since all Field subclasses have required=True by default, the validation condition here is important. If you want to include a boolean in your form that can be either True or False (e.g. a checked or unchecked checkbox), you must remember to pass in required=False when creating the BooleanField.



So, add required=False in BooleanField() as,

class AddItemToCartForm(forms.Form):
    part_id = forms.IntegerField()
    is_kit = forms.BooleanField(required=False)


Additional Info:
When the checkbox isn't checked, browsers do not send the field in the POST parameters of requests. Without specifying that the field is optional Django will treat it as a missing field when not in the POST parameters.

Reference : SO Post

JPG
  • 82,442
  • 19
  • 127
  • 206
  • This works for me, but I think I'm a bit confused. Wouldn't having it required just mean that there should exist a value in the post data for `is_kit`, True or False? It seems like `required=True` in this case is literally saying that the value must evaluate to `True` for the BooleanField? – Grayson Pike Aug 20 '18 at 18:48
  • 1
    Ah, this makes sense now. Thank you! – Grayson Pike Aug 20 '18 at 19:26
0

You need to add required=False to your BooleanField:

class AddItemToCartForm(forms.Form):
    part_id = forms.IntegerField()
    is_kit = forms.BooleanField(required=False)
Cyrlop
  • 1,894
  • 1
  • 17
  • 31