The Python Oracle

Django: Why does NullBooleanField accept non-boolean answers?

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: The Builders

--

Chapters
00:00 Django: Why Does Nullbooleanfield Accept Non-Boolean Answers?
00:26 Accepted Answer Score 6
01:40 Thank you

--

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

--

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.