Django: Why does NullBooleanField accept non-boolean answers?
django, python
Solution
Because `NullBooleanField` is just trying to convert to a Python object, in this case either `None`, `True`, or `False`.
Thus, anything `bool` casting will work on, will work on this field, since that's what it does in the background.
Edit:
This may be a bug. Looking at the source code for this, you can see it is only supposed to accept the values `True`, `False`, `None`, `'t'`, `'f'`, `'True'`, `'False'`, `'None'`, `'0'`, and `'1'` (not even `0` and `1`!). This has been the case at least since Django 1.5. What version of Django are you using?
Edit 2:
I tried to reproduce this using Django 1.7 and had even weirder results.
>>> zoo = Zoo.objects.create()
>>> zoo.lion = 'Simba'
>>> zoo.save()
>>> zoo.lion
'Simba'
>>> type(zoo.lion)
<type 'str'>
Of course, I have just overwritten the attribute on the local object here. I can also do this:
>>> zoo.walrus = 'Simba'
>>> zoo.walrus
'Simba'
However, when I refresh the local object by pulling it back out of the database:
>>> zoo = Zoo.objects.get(pk=1)
>>> zoo.lion
True
>>> type(zoo.lion)
<type 'bool'>
At no point was an exception raised, but it did get converted to a boolean. I'm beginning to second-guess where `to_python` even gets called.
Problem
Say I have a NullBooleanField on the Zoo model: ``` class Zoo(models.model): lion = NullBooleanField() ``` Why does it let me save a non-boolean field which then defaults to true, rather than erroring out? For instance: ``` my_zoo = Zoo.objects.create() my_zoo.lion = "Simba" my_zoo.save() # Surprisingly, no error here. >>>my_zoo.lion # True ```