Reminder: after Django 1.5, default value for BooleanField is None, not False!
It's mentioned explicitly in the Django 1.6 release docs but still caught me by surprise: the default value for django.db.models.BooleanField is now None not False. This means that if the corresponding field in your database is something like tinyint not null default 0 you will encounter an error on record creation like:
Cannot insert the value NULL into column 'some_truefalse_value', table 'db.dbo.Foo'; column does not allow nulls. INSERT fails.
That's because Django explicitly inserts values for all columns, even ones it does not have data for, and where before the value was False which rendered as 0 in the SQL query, it is now None which renders as NULL.
The Django developers explain the change thusly:
In previous version of Django, it was False, but that didn’t represent accurately the lack of a value.
I disagree with this decision on the part of the Django developers, because:
there is already a NullBooleanField field type which covers boolean values with an optional "No Value".
it is reasonable to consider that for a data type in which the only possible values are true and false that the absence of a value equates to false — particularly in the context of a language where None and blank are considered falsey.
it requires users to make changes everywhere in their code, and rely on the developers of the libraries they use to make similar changes
Personally, I think that when it comes to a determination whether a change should be made to a section of code, "will break existing behavior" should trump "is very slightly ideologically inconsistent".
Also, you want to talk about inconsistent?
The default/empty value for django.forms.fields.BooleanField is False! That's because, if it wasn't, when a checkbox was left unchecked the value in the corresponding field would be None. As far as I can tell, BooleanField is the only field for which the default value of the form Field is different than the default value for the model Field.
So I will now be wasting time going through all of my code and adding default=False to all BooleanFields in my code. And I will either be looking for updates of libraries I am using that make use of BooleanFields, or modifying my existing installs.
BTW, I upgraded from 1.5 to 1.7 (now that 1.5 is officially no longer supported) and this change was not listed on the "deprecation timeline" which states that it "outlines when various pieces of Django will be removed or altered in a backward incompatible way. Changing False to None is a backwards incompatible change. There were no warnings of this change in the 1.5 release. The only place that mentions the change is the release notes for 1.6. That means that developers like me, who wrote prior code based on established behavior, will not discover this change unless they make a practice of reading all past release notes when upgrading, or until it causes an error when the code is updated.
The ticket in question Apparently this has been in the works since Django 1.3!