BooleanField and NullBooleanField (#2855 again)

382 views
Skip to first unread message

Mads Sulau Joergensen

unread,
Jun 24, 2007, 11:35:46 AM6/24/07
to Django developers
Hi.

Having looked at #2855 and wondered the resolution of that ticket, i
wanted to raise the discussion again.

To me, and many others, it makes absolutly no sense, that a
BooleanField with no default value given, sould yield a SQL error
uppon saving it.

The ticket states that a BooleanField should be given a default value
of False, and that null's should not be allowed, and I can only say
that i agreed with that. After all, that is what NullBooleanField is
there for - right?

If anyone can think of a valid reason for a bool to be '' (not null,
not true, not false, but en empty string) please do speak up :)

--
Mads Sulau Joergensen

Carl Karsten

unread,
Jun 24, 2007, 12:04:42 PM6/24/07
to django-d...@googlegroups.com
Mads Sulau Joergensen wrote:
> Hi.
>
> Having looked at #2855 and wondered the resolution of that ticket, i
> wanted to raise the discussion again.
>
> To me, and many others, it makes absolutly no sense, that a
> BooleanField with no default value given, sould yield a SQL error
> uppon saving it.
>
> The ticket states that a BooleanField should be given a default value
> of False, and that null's should not be allowed, and I can only say
> that i agreed with that. After all, that is what NullBooleanField is
> there for - right?

I can mostly agree with that.

Here is why not 100%: replace "should be given a default" with "it would be
handy if it had a default" - if anything should happen, it is the application
developer (aka db designer) needs to specify a default.

however, I think consistency is good, and giving everything a reasonable default
is better than giving some things a default.

"Note that empty string values will always get stored as empty strings, not as
NULL." http://www.djangoproject.com/documentation/model-api/#null

The reasonable default for a date is NULL.

>
> If anyone can think of a valid reason for a bool to be '' (not null,
> not true, not false, but en empty string) please do speak up :)

No, if anyone thinks they know a reason, they should keep their mouth shut :)

I have heard this discussion before applied to dates: "a blank date is different
than an empty date." I think the discussion ended because the bar closed.

As for blank bools, I am pretty sure that is outside the definition of a bool.

Carl K

Malcolm Tredinnick

unread,
Jun 24, 2007, 9:06:10 PM6/24/07
to django-d...@googlegroups.com
On Sun, 2007-06-24 at 08:35 -0700, Mads Sulau Joergensen wrote:
> Hi.
>
> Having looked at #2855 and wondered the resolution of that ticket,

There's been no resolution on that ticket, from what I can see. Still
open.

> i
> wanted to raise the discussion again.
>
> To me, and many others, it makes absolutly no sense, that a
> BooleanField with no default value given, sould yield a SQL error
> uppon saving it.

Since that is what happens with every other field, it's logical
behaviour, though. To be consistent, you would have to argue that every
field without a default attribute should have some default value and
we've already decided in the negative on that one.

Saving a model that you haven't validated is bad practice in Django. The
validation and saving processes have been separated by design. The
reason for that has been explained in other posts on this list over the
years.

> The ticket states that a BooleanField should be given a default value
> of False, and that null's should not be allowed, and I can only say
> that i agreed with that. After all, that is what NullBooleanField is
> there for - right?

There seems to be some confusion in that ticket as to both what the
ticket is about and what the purpose of NullBooleanField is. Remember
that some field types in Django have a history behind them and that
history is often "was needed for something back in 2004 before Django
was open-sourced."

Firstly, the consistency points: any field without null=True specified
in the model needs to have a value set. That is true for all fields;
shouldn't be an different for BooleanField.

Secondly (and this is the historical legacy issue), NullBooleanField is
an example of a leaky abstraction: it's a field that, when you present
it to the user on a form, is intended to be a tri-state:
true/false/unknown. BooleanField, in a form context, is only a binary
field: true/false. So the difference between NullBooleanField and
BooleanField is presentational. However, that isn't really a strong
argument for saying you can't put null=True on BooleanField, because
models data storage is, ideally, independent of presentation. It will
mean exactly what it means for all other fields (consistency again): the
value is not yet determined.

Assertions that BooleanField can *only* be true or false is working
backwards from form presentation and/or trying to justify
NullBooleanFields existence. I don't find either of those arguments as
particularly compelling.

The fact that we have NullBooleanField for legacy reasons does not mean
that BooleanField should behave specially and somehow different from
other fields. Consistency is very important for developers: having an
API that behaves as one expects is a time-savers and leads to less bugs.
By and large, you can ignore NullBooleanField and your life will not be
any worse off.

Consistency in API seems to imply that "null=True" should always works
and permits empty values to be stored. It also means fields without a
default need a value to be set.

I haven't looked at that ticket for a while, but I'm inclined to say
it's not a bug. Will wait to here for input from some other core
developers first, though, since Jacob and Adrian were there at the time
and might have other motivations or knowledge (I'm pretty strong no
data/presentation separation -- with good reason and because it's what
all right-thinking people do :-) -- but that doesn't mean it's the way
we always go).

Regards,
Malcolm

Mads Sulau Joergensen

unread,
Jun 25, 2007, 3:57:18 AM6/25/07
to Django developers
On Jun 25, 3:06 am, Malcolm Tredinnick <malc...@pointy-stick.com>
wrote:

> Consistency in API seems to imply that "null=True" should always works
> and permits empty values to be stored. It also means fields without a
> default need a value to be set.

You make a very good point. However I still think that it at least
should be documented, that a BooleanField will not be saved, if not
given either a default value or a value. E.g. "BooleanField: A true/
false field. NOTE: Unless null = True, this field requires value.".

And I still think it's a bit much letting such a problem get all the
way to the db.

> I haven't looked at that ticket for a while, but I'm inclined to say
> it's not a bug.

What ever it is, my life would have been 30 minutes easier if it were
documented, or transparent.

--
Mads Sulau Joergensen

Tai Lee

unread,
Jun 26, 2007, 8:23:12 PM6/26/07
to Django developers
I would have thought it's obvious. Any fields are are not null=True
must have a default specified in the model or a value explicitly
provided before calling save(). However, I just did a quick double-
take and it looks like CharField actually has an implicit default of
"" already. If CharField can have an implicit default of '', I don't
see why BooleanField can't have an implicit default of False (empty),
or why IntegerField can't have an implicit default of 0.

Personally, I'd rather vote for the removal of 'empty' defaults from
CharField than their addition to BooleanField and IntegerField. If you
want a default of False, or 0, or "", just specify those in your
model. Why is there an implicit default of "" on CharField anyway?

SmileyChris

unread,
Jul 31, 2007, 10:12:48 PM7/31/07
to Django developers
/me pulls out his horse-beating stick...

First off, the patch in the ticket [1] this thread mentions isn't the
correct solution. Better would be to change the .get_default() method
of BooleanField.
[1] http://code.djangoproject.com/ticket/2855

On Jun 25, 1:06 pm, Malcolm Tredinnick <malc...@pointy-stick.com>
wrote:

> > To me, and many others, it makes absolutly no sense, that a

> >BooleanFieldwith no default value given, sould yield a SQL error


> > uppon saving it.
>
> Since that is what happens with every other field, it's logical
> behaviour, though.

Actually, this is *not* what happens with every other field.
I just had a look at the issue again today - other fields use
"empty_strings_allowed = False" which makes the return value None
instead of an empty string.

> To be consistent, you would have to argue that every
> field without a default attribute should have some default value and
> we've already decided in the negative on that one.

...

> Firstly, the consistency points: any field without null=True specified
> in the model needs to have a value set. That is true for all fields;
> shouldn't be an different for BooleanField.

This is *not* true for all fields. The default value of an empty
string is automatically chosen for most fields (ones without
"empty_strings_allowed = False") even if null != True.

If text-based fields are allowed to have their .get_default() method
decide on an empty string if not self.null, why shouldn't BooleanField
be allowed to decide on False if not self.null.

>
> Secondly (and this is the historical legacy issue), NullBooleanField is
> an example of a leaky abstraction: it's a field that, when you present
> it to the user on a form, is intended to be a tri-state:

> true/false/unknown.BooleanField, in a form context, is only a binary
> field: true/false. So the difference between NullBooleanField andBooleanFieldis presentational. However, that isn't really a strong
> argument for saying you can't put null=True onBooleanField, because


> models data storage is, ideally, independent of presentation. It will
> mean exactly what it means for all other fields (consistency again): the
> value is not yet determined.
>

> Assertions thatBooleanFieldcan *only* be true orfalseis working


> backwards from form presentation and/or trying to justify
> NullBooleanFields existence. I don't find either of those arguments as
> particularly compelling.

Actually, my assertion of this fact was that its .to_python() method
raises a ValidationError if its value is neither True nor False.
If you let it be None, you'll start breaking things like the
serializer (and model level validation when that gets looked at :))

> Consistency in API seems to imply that "null=True" should always works
> and permits empty values to be stored. It also means fields without a
> default need a value to be set.

I concur. So short of any other changes I have suggested, BooleanField
should be changed to set "empty_strings_allowed = False", since
currently it tries to set it with an empty string.

SmileyChris

unread,
Sep 16, 2007, 5:42:49 AM9/16/07
to Django developers
Reading http://code.djangoproject.com/ticket/3997, I think this covers
the BooleanField side of thinsg
Reply all
Reply to author
Forward
0 new messages