Django blank vs null: What’s the Real Difference?

This post will explain the Django blank vs null concept. The difference between blank=True and null=True is a confusing concept in Django models and this post will demystify it.

What does null mean?

Null in Database management basically means a value is not known or is not valid for that database table.

The confusion of not knowing what null really refers to when dealing with databases comes from the English definition of the word. If you use a dictionary to search for what null means, most of them will generally point to it having to deal with the value zero.

However, this is not true when working with databases. Null is neither a zero nor an empty string. It is just a keyword for a value that is there but we do not know its actual value, we cannot measure it… it is invalid. But for that reason, it does not mean blank either. It means the value is there, but for whatever reason, we just do not know what the value is.

Example:

Let’s say we are building a school management database scheme. There is a Student table that requires us to enter the age of the student. If there is a student record with the age field null. What does that mean? Well, it may mean 2 of the following things:

  1. The value entered for the age field is not valid. Maybe it’s a string value when it was supposed to be a number.
  2. The value was not entered. This means that we do not know the age of the student.

This does not mean the following:

  1. The age of the student is zero. Just because we do not know the actual value does not mean it’s a zero. Yes, the age could be zero but we just do not know if it is or if it isn’t.🤓
  2. The student does not have any age. Maybe only if the dude is infinite. ha ha.

I hope that was not too much of a hack to understand. One thing to note before we move forward is, null is a database value, which means you can actually provide it as a valid value in your database values.

The blank option.

Unlike the null option, the blank value is not actually a possible database record keyword. In other words, you cannot have a database record with the value of ‘blank’ just like you’d see with the null value. So how does the database know that the record is empty? Well, this can be denoted in one of the following ways:

1. An empty string. A string with no characters.
2. A string with blank spaces only.

That’s how the database knows if a value is blank or not.

Going back to our school management project example. If a record has an empty string, instead of null, it means that the record was left empty. Just empty. That’s all.

In real projects, as we all know, the user will not interact with the database directly. When you specify blank=True, it means that Django allows the user to leave the form input for that record empty. When a user does so, this is going to be recorded in the database as an empty string.

Blank vs Null

This leaves us to the conclusion that the null option is used for database records (when you have direct access to the database) while the blank option is used for frontend form validation.

Let’s see some scenarios so that you can understand better.

When We Don’t Specify blank and null values.

By default, both of the values are set to False. This means that if you do not specify the values explicitly, Django will regard it as both blank=False and null=False. This means that from the frontend side, the value for that field will be required. If it is not provided, it will throw an error. On the backend side, it means that the value cannot be saved as null and as a result, an error will also be thrown from the database.

When null = True and blank = False.

When null = True, this tells our database that null value is permitted for that record. However, this is problematic because blank = False makes the value for the record mandatory on the frontend side. So the error we will get will be from the frontend rather than the backend.

Case Study 1: Testing when null=True and blank=False

There is a way to test this out. Suppose we have the following table in our database.

class Student(models.Model):
     name = models.Charfield(max_length = 30, null = True)
     age = models.Intergerfield(null = True)

     def __str(self):
         return f('Name: {self.name} Age: {self.age}')

As you can see, we have set null = True for both fields (name and age). Let’s add instances to this class in two ways, one with shell and the other with the Django admin panel. The reason we are doing this is that the shell offers direct access to the database while the Django admin adds a layer of frontend that has forms that require validation.

Let’s suppose you have already created a Django project, a suitable Django app and you’ve created the above table.

Adding Values from the Shell

After creating the model, make sure you make migrations for your app and then you migrate it.

To use the shell, open the terminal and cd to the root project folder. If you are using a virtual environment, make sure you activate it. Run the following command to open the shell.

(env) $ python manage.py shell

Next, we have to import our model.

>>> from demo.models import Student

In this case, demo is the app that contains the Student model.

Let’s now create an empty object of the Student class and save it to the database.

>>> student1 = Student()
>>> student1.save()

Note that, although we did not enter data for the Student model, we do not get any error upon saving. Let’s now check the objects in our class and see how they have been saved in the database.

>>> Student.objects.all()
<QuerySet [<Student: Name: None, Age: None>]>

And that is what you should get. The name is None and the Age is also None.

Adding Values from the Admin.

Now let’s shift to the frontend by accessing the Django admin panel. Start by registering your models to the admin.

Create a superuser and then in your browser navigate to http://127.0.0.1:8000/admin where you will be redirected to the login page. Use the details for the superuser to log in to the admin panel.

Django Blank vs Null: Adding Values from the Admin.

There you should see the model Student(s) under DEMO. We want to add some objects to the student model. So click the +Add link. On the next page, let’s try to save without having any information added.

This is what you will get.

I hope this has elaborated. Let’s see what happens when blank = True and null = False.

When blank = True and null = False.

When blank=True and null=False, it will permit the form for the record to be left empty upon saving. This will not throw an error from the frontend side, but the error will come from the database.

Case Study 2: Testing When blank = True and null = False

To follow along, start by deleting the migration files in the migration folder of your app and leave out the __init__.py, then delete the db.sqlite3 file.

Change the previous code to look like the one below. I have replaced the keyword null with blank.

class Student(models.Model):
     name = models.Charfield(max_length = 30, blank=True)
     age = models.Intergerfield(blank=True)

     def __str(self):
         return f('Name: {self.name} Age: {self.age}')

Then make migrations and run the migrate command. We did this to clean up our project so that I can illustrate the next scenario.

Adding Values with the Shell.

In your terminal, go back to the shell and add another empty object like below. Spoiler: you will get a massive error.

>>> from demo.models import Student
>>> student2 = Student()
>>> student2.save()

Okay, let’s look at what the error says:

django.db.utils.IntegrityError: NOT NULL constraint failed: demo_student.ag

We are getting this error because we have not permitted our database to store null values.

Adding Values from the Admin.

Create the superuser, run the server, and log in to your admin panel.

Let’s try to save a student without any information. This is what happens:

We of course get an error, but the error is not from the frontend like we have seen from the previous scenario. If you look closely, it’s the same error that we got from the shell. It says: NOT NULL constraint failed: demo_student.age.

That’s what we expected!

When blank = True and null = True.

When both ‘blank’ and ‘Null’ are set to True, the frontend allows the saving of empty records, which the database will also store without issue. This configuration ensures that records can be saved even when they contain no data, providing flexibility in data management.

This is the ideal setup for any fields where user input is optional.

Case Study 3: Checking When Both Blank and Null are Set to True.

Delete the migration files in the migration folder of your app and leave out the __init__.py, then delete the db.sqlite3 file (just like you did in the previous section).

Change the previous code to look like the one below. I have included both blank = True and null = True.

class Student(models.Model):
     name = models.Charfield(max_length = 30, blank=True, null = True)
     age = models.Intergerfield(blank=True, null = True)

     def __str(self):
         return f('Name: {self.name} Age: {self.age}')

After that, make migrations and run the migrate command.

Adding Values with the Shell.

Go to the shell and add an empty object.

>>> from demo.models import Student
>>> student3 = Student()
>>> student3.save()

See? Our empty object has been added to the database just like on the first case study. Let’s check what it looks like.

>>> Student.objects.all()
<QuerySet [<Student: Name: None, Age: None>]>

Name has a None value and so does Age.

Adding Values from the Admin.

Next, we’ll take a look at the front end. Create the superuser, run the server, and log in to your admin panel. Hit the save button without adding any information. Your Student object will be added successfully.

So, What’s the difference between blank=True and null =True in Django models?

From the four above scenarios we have analyzed, we can conclude that blank is used for frontend form validation while null is used for backend data validation(that is the database). This is why the fourth scenario has become so popular when working with fields whose value is not required. So whenever you want to create such a field, now you know what to do, just include both blank = True and null = True and you will be good to go.

Stephen Mclin
Stephen Mclin

Hey, I'm Steve; I write about Python and Django as if I'm teaching myself. CodingGear is sort of like my learning notes, but for all of us. Hope you'll love the content!

Articles: 125