User0511
User0511

Reputation: 725

How can I resolve the Django error "add a non-nullable field"?

I am getting an error regarding a Django model when I try to run makemigrations:

You are trying to add a non-nullable field 'person' to owner without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:

  1. Provide a one-off default now (will be set on all existing rows)
  2. Quit, and let me add a default in models.py

I am using Django 1.8 and this is my model:

class Person(models.Model):
    user            = models.OneToOneField(User)
    alphanumeric    = RegexValidator(r'^[0-9a-zA-Z]*$', message='hanya yang mengandung karakter alphanumeric')
    email           = models.EmailField(verbose_name='email address', unique=True, max_length=244)
    username        = models.CharField(unique=True, max_length=20, validators=[alphanumeric])
    first_name      = models.CharField(max_length=30, null=True, blank=True)
    last_name       = models.CharField(max_length=30, null=True, blank=True)
    date_of_birth   = models.DateTimeField()
    date_joined     = models.DateTimeField(auto_now_add=True)


    USERNAME_FIELD      = 'username'
    REQUIRED_FIELDS     = ['email']

    def get_full_name(self):
        fullname = self.first_name+" "+self.last_name
        return self.fullname

    def get_short_name(self):
        return self.username

    def list_operator(self):
        return self.operators.all()

    def __str__(self):
        return self.email

class Operator(models.Model):
    person          = models.ForeignKey(Person, related_name="operators", null=True)
    alphanumeric    = RegexValidator(r'^[0-9a-zA-Z]*$', message='hanya yang mengandung karakter alphanumeric')
    email           = models.EmailField(verbose_name='email address', unique=True, max_length=244)
    username        = models.CharField(unique=True, max_length=20, validators=[alphanumeric])
    first_name      = models.CharField(max_length=30, null=True, blank=True)
    last_name       = models.CharField(max_length=30, null=True, blank=True)
    date_of_birth   = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.username;

Can you help me solve this problem?

Upvotes: 4

Views: 12118

Answers (2)

AnoMorCH
AnoMorCH

Reputation: 63

If you don't want to have null=True property in your model or set a FK instance manually which isn't a simple task sometimes, you can do the following:

  1. Delete all instances of Person and Operator models from your DB (e.g. using DjangoAdmin).
  2. Set null=True of the FK field of your child model (field person of model Operator in your case).
  3. Run python manage.py makemigrations.
  4. Delete null=True property from p. 2.
  5. Run python manage.py makemigrations again.
  6. When running makemigrations from p. 5, you need to choose 2) Ignore for now. Existing rows that contain NULL values will have to be handled manually, for example with a RunPython or RunSQL operation.
  7. Run python manage.py migrate.

The main downside of the method is that you have to delete all instances of at least two your models which isn't always acceptable. However, I'm sure if it isn't your case, this is the best way to solve the error.

Upvotes: 3

rnevius
rnevius

Reputation: 27112

Your code isn't wrong. Just follow the instructions provided by the message...

The person field within your Operator model can't be null (because null=True isn't set). You must already have Operators in your database, so Django doesn't know what to do with those.

You need to either: (a) provide a default value in your model, (b) provide a default during the migration process, or (c) enable null values for that field.

Upvotes: 8

Related Questions