views:

124

answers:

3

Hello all,

I'm using a Django ModelForm where my model contains a BooleanField and the form widget associated with that BooleanField is a RadioSelect widget. I'd like the the RadioSelect widget that renders to have no options selected so the user has to explicitly make a choice, but the form validation to fail if they make no selection. Is there a way to do this?

models.py

myboolean = models.BooleanField(choices=YES_NO)

forms.py

class myModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(myModelForm, self).__init__(*args, **kwargs)
        self.fields['myboolean'].widget = forms.RadioSelect(choices=YES_NO)
+2  A: 

Your code actually does what you need. It renders the radio buttons with no options selected and generate the error message if nothing is selected.

A small note about your form code. I would do it like this:

class myModelForm(forms.ModelForm):

    myboolean = form.BooleanField(widget=forms.RadioSelect(choices=YES_NO))

    class Meta:
        model = MyModel
Andrey Fedoseev
Thank you Andrey. After seeing your solution, I reexamined my situation and found my simplified example cut out an important piece of information. A ModelField override that was in place was interfering with the default value. I learned from this problem that RadioSelect fields seem to by have default=None set. The override that I had in place was setting the default to False. (By the way, I was using the __init__ function because I didn't want to trump any default values set by the model, such as label).
Joe J
Thank you again for your help with this and sorry for the bad example. I was trying to strip the problem down to its core, but missed some information.
Joe J
+1  A: 

Unfortunately, this is less of a Django issue than an HTML question. The HTML specification (RFC1866) says:

At all times, exactly one of the radio buttons in a set is checked. If none of the <INPUT> elements of a set of radio buttons specifies `CHECKED', then the user agent must check the first radio button of the set initially.

However, browsers have historically ignored this and implemented radio buttons in different ways.

HTML also makes this difficult because the "checked" attribute of the <INPUT> tag doesn't take a parameter, so you can't use a customized Django widget that sets this attribute to False or No.

A possible workaround is to put in a little Javascript that runs as part of the document's onLoad event that finds all the radio buttons on the page and sets the 'checked' attribute to false (using JQuery, for example).

KeithL
I like the workaround with the javascript to erase the checked values. My only fear is that Django won't complain about the empty radio button boxes and evaluate them to false. I'd rather it throw a validation error.
Joe J
As Andrey mentions below, if a radio button isn't selected, then Django should throw a validation error, since 'required' defaults to True.
KeithL
That's good to know. I wasn't sure how a BooleanField would impact the RadioSelect widget since it seems like a lot examples that I found use an IntegerField. Thanks for your input.
Joe J