[Fixed]-Django: how to change values for nullbooleanfield in a modelform?


I spent half an hour putting together a demo just to prove to myself this works:

    (None, "I do not know now"),
    (True, "Yes I acknowledge this"),
    (False, "No, I do not like this")

class Demo(models.Model):
    yes_no_required = models.NullBooleanField(choices = CHOICES)

class DemoForm(forms.ModelForm):
    class Meta:
        model = Demo

I looked in the Django source code. Everything can accept a choices array. Obviously, for some of those that doesnโ€™t make sense, but itโ€™s possible.

๐Ÿ‘คElf Sternberg


You can handle this in a form (withouth modifying the models) like this:


I think it is a bad idea to use NullBooleanField for data which can be in three states like: yes/no/unset.

Editing the data works. But the big trouble arises if you want to write a search form for this data.

Then the โ€œemptyโ€ values can have two meanings:

  • Donโ€™t care for this attribute. Include all rows
  • Include only these rows, where the column is NULL.

The solution is simple: Use a ChoiceField.

More details here: https://github.com/guettli/programming-guidelines/blob/master/README.rst



You can modify your field widget in your ModelForm meta class:

            (None, "I do not know now"),
            (True, "Yes I acknowledge this"),
            (False, "No, I do not like this"),
class DemoForm(forms.ModelForm):
    class Meta:
        model = Demo
        fields = ("demo_field",)
        widgets = {
              'demo_field': forms.RadioSelect(choices = CHOICES),


Simple approach would be to change widget choices in your form:

class YourForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(YourForm, self).__init__(*args, **kwargs)
        new_choices = ((1, 'I do not know now'),
                       (2, 'Yes I acknowledge this'),
                       (3, 'No, I do not like this'))
        self.fields['your_field'].widget.choices = new_choices

Leave a comment