41👍
The question you need to answer to find out whether you should use the BooleanField
or the NullBooleanField
is actually concerning the possible states of the value of the field you want to represent in your model:
2 possible states:
- user has drunk water
- user has not drunk water
→ use BooleanField
3 possible states:
- user has drunk water
- user has not drunk water
- it is not known whether the user has or has not drunk water
→ use NullBooleanField
.
UPDATE:
NullBooleanField
is deprecated in version 3.1. Instead use BooleanField
with null=True
.
10👍
Django 2.1 introduced null=True
for BooleanField
. Using NullBooleanField
is now discouraged.
So use, x = BooleanField(null=True)
instead of x = NullBooleanField()
Here’s a simple use case: If you only need to record the “Yes” or “No” status, use Boolean without null. But if you want to have 3 conditions say, “Yes”, “No”, and “Don’t Know”, use it with null=True
.
- How to convert request.user into a proxy auth.User class?
- Error: command 'x86_64-linux-gnu-gcc' when installing mysqlclient
- What is the IP address of my heroku application
- Google App Engine Application Extremely slow
- Django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'auth.User' that has not been installed
1👍
I think you should use NullBooleanField
only when you have three possible choices: Unknown, Yes (True) and No (False).
In your case you have only two possible values – Yes (user has drunk water) and No (user has NOT drunk water) so a BooleanField
would be better.
One more reason to use a BooleanField
in your case is because the default form widget for this field is a CheckboxInput
(docs), while the default form widget for a NullBooleanField
is a NullBooleanSelect
(docs). And since you use a checkbox, a BooleanField
would do the job better.
0👍
Take advantage of the NULL properties
I use it quite often when I need to enforce some specific constrains in my data, but allow some others. Multiple NULL
values can coexist in a column defined UNIQUE
. Let’s take an address model implementation as an example:
The business rules are:
- A user can have up to 1 billing address
- A user can have multiple shipping addresses
One way to implement that is by making a single address
table with a foreign key to the user
and an extra flag that indicates if that address is a billing address or not:
class Address(models.Model):
... # <- address fields
user = models.ForeignKey(User, on_delete=models.CASCADE)
billing_address = models.NullBooleanField(default=None)
You can now simply enforce the business rules at a database level by making user
and billing_address
unique together.:
class Meta:
constraints = [
models.UniqueConstraint(
fields=['user', 'billing_address'],
name='ensure single billing address'
)
]
The trick to make this work is that the billing_address
must be True
when the address is a billing address but it should be None
(instead of False
) when the address is a shipping address.
You can further enforce the validation by adding another constraint to make sure that no False
values are added. But this is usually not necessary and could be done at the application level:
class Meta:
constraints = [
models.UniqueConstraint(
fields=['user', 'billing_address'],
name='ensure single billing address'
),
models.CheckConstraint(
check=~Q(billing_address=False),
name='no False allowed'
)
]
- Is there any list of blog engines, written in Django?
- Why does Django South require a default value when removing a field?
0👍
Biggest advantage of using NullBooleanField
for PostgreSQL database is your table won’t be re-written, any new field without null=True
will cause a table re-write, it’s fine for small tables but could take a significant amount of time and resource for large tables and you won’t be able to write to your table during a re-write
- Reset SQLite database in Django
- Django Rest Framework debug post and put requests
- Django admin dropdown of 1000s of users
- How to combine django plus gevent the basics?
- Django, REST and Angular Routes