开发者

django: how to change values for nullbooleanfield in a modelform?

In the docs, the nullbooleanfield is represented as a <select> box with "Unknown", "Yes" and "No开发者_C百科" choices. How can I change the values of select to some other more meaningful texts and map it back to the yes,no and unknown values in my modelform?

For example I have yes_no_required = models.NullBooleanField() and I would like to have 'yes I acknowledge this', 'no, I do not like this' and 'I do not know now' mapping to yes, no and required accordingly.


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

CHOICES = (
    (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.


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

forms.NullBooleanField(
    widget=forms.RadioSelect(renderer=HorizontalRadioRendererSpace,
        choices=CHOICES),
    label='...',
    required=False)

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:

CHOICES = (
            (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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜