The real difference between blank=True and null=True may surprise you
Expect the unexpected if null
and blank
are different values: null
controls if the the database level validation allows no value for the field, while blank
controls if the application level validation allows no value for the field.
If blank=True
then the field model validation allows an empty value such as ""
to be inputted by users. If blank=False
then the validation will prevent empty values being inputted.
On the other hands, null
informs the database if the database column for the field can be left empty, resulting in the database setting either NULL
or NOT NULL
on the column. If the database encounters an empty NOT NULL
column then it will raise an IntegrityError
.
blank
is used during during field validation. Form
, ModelForm
, and ModelSerializer
each trigger field level validation. For a concrete example, ModelForm
calls the model instance’s full_clean
method during form validation, and full_clean
then calls clean_fields
, which in turn may raise a ValidationError
.
So normally we want null
and blank
to the same value, right? If null=True
then blank
should be True
and vice versa, yes? When would we want to have null=False
and blank=True
or even null=True
and blank=False
?
null=False, blank=True
This facilitates using sensible default values for string fields: the field may have a default value like name = CharField(null=False, blank=True, default="")
. This is useful if the field is optional, but we also want to prevent the database column from having inconsistent data types. Sometimes being None
, sometimes being ""
, and other times being a non-empty string causes extra complexity in code and in ORM: if we wanted to find all users with no name:
Foo.objects.filter(name="") | Foo.objects.filter(name__isnull=True)
Compare that with the case for when the value in the database column will always be a string:
Foo.objects.filter(name="")
null=True, blank=False
This scenario is more to keep the database happy.
If using the django.db.backends.oracle
database engine then this may be needed because Oracle forces empty strings to NULL, even if an empty string was submitted in the form, so name = CharField(null=True, blank=False)
would be needed.
Zero downtime deployment strategies may required NULL on the database column, even though business requirements dictate the user must enter a value in the form. During blue/green deployments both the new codebase and the old codebase run against the same database at the same. If the new codebase adds a new fields and there is no sensible default value for it then null=True
is needed to avoid the database throwing an IntegrityError
while the instance of your website running the old codebase interacts with the database.
While the database column can accept null, form validation can prevent the end users inputting no value, so data type consistency is assured? No — this required the form validation to actually run. If a developer is creating or updating via the shell then the validation will not run unless the developer calls instance.full_clean()
or instance.clean_fields()
. This strategy is simplified if a sane default value can be used instead of setting null=True
.
I’m a GitHub bot that checks pull requests and makes Django improvements. You can check your entire codebase at django.doctor or install the GitHub PR bot to reduce dev effort during code review and improve your code with no cost.