Fields created NO NULL despite the parameter blank=True, null=True

Hello there, please review the model that I am defining and the SQL contents.
models.py

from django.db import models
from django.contrib.auth.models import User

# Create your models here.
class Profile(models.Model):
    USER_TYPE_CHOICES = (
        ('Donor', 'Donor'),
        # first is actual value, second is human-readable placeholder
        ('Seeker', 'Seeker'),
    )
    BLOOD_GROUP_CHOICES = (
        ('A+','A+'),
        ('A-','A-'),
        ('AB+','AB+'),
        ('AB-','AB-'),
        ('B+','B+'),
        ('B-','B-'),
        ('O+','O+'),
        ('O-','O-'),
    )
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField( max_length=15)
    blood_type = models.CharField(max_length=3, choices=BLOOD_GROUP_CHOICES, blank = True, null=True)
    user_type = models.CharField(max_length=10, choices=USER_TYPE_CHOICES, null=True, blank=True)
    contact_number = models.IntegerField(null=True, blank=True)

    def __str__(self):
        return self.name

signals.py

from django.dispatch import receiver
from allauth.account.signals import user_signed_up
from .models import Profile

@receiver(user_signed_up)
def create_profile(user, **kwargs):
    Profile.objects.create(user=user, name=user.username)

$ python3 manage.py sqlmigrate dashboard 0001.
dashboard is the name of the app where models.py resides, See the SQL that it showed

BEGIN;
--
-- Create model Profile
--
CREATE TABLE "dashboard_profile" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(15) NOT NULL, "blood_type" varchar(3) NOT NULL, "user_type" varchar(10) NOT NULL, "contact_number" integer NOT NULL, "user_id" integer NOT NULL UNIQUE REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED);
COMMIT;

There are two confusions;
1. In models.py fields blood_type, user_type and contact_number are defined with null=True and blank=True. Still, CREATE TABLE defines these fields as NOT NULL. Why this?

2. Signals.py creates a new instance of Profile as; Profile.objects.create(user=user, name=user.username), clearly providing user and name fields only and not providing blood_type, user_type and contact_number. But as shown in the SQL contents, blood_type, user_type and contact_number were defined as NO NULL, why not Profile.objects.create(user=user, name=user.username) statement expects the values for blood_type, user_type and contact_number?

You can read the full story in case you are interested :slight_smile:

Regards

I can see where you’ve run the first migration here.

Please post the output of a showmigrations command.

$ python3 manage.py showmigrations

Blood
 (no migrations)
account
 [X] 0001_initial
 [X] 0002_email_max_length
 [X] 0003_alter_emailaddress_create_unique_verified_email
 [X] 0004_alter_emailaddress_drop_unique_email
 [X] 0005_emailaddress_idx_upper_email
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
 [X] 0012_alter_user_first_name_max_length
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
dashboard
 [X] 0001_initial
 [X] 0002_alter_profile_blood_type_and_more
sessions
 [X] 0001_initial
socialaccount
 [X] 0001_initial
 [X] 0002_token_max_lengths
 [X] 0003_extra_data_default_dict
 [X] 0004_app_provider_id_settings
 [X] 0005_socialtoken_nullable_app
 [X] 0006_alter_socialaccount_extra_data