The Python Oracle

Django: Why does NullBooleanField accept non-boolean answers?

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Lost Civilization

--

Chapters
00:00 Question
00:31 Accepted answer (Score 6)
02:15 Thank you

--

Full question
https://stackoverflow.com/questions/2861...

Accepted answer links:
[source code for this]: https://github.com/django/django/blob/ma...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #django

#avk47



ACCEPTED ANSWER

Score 6


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.