155

I know that from Django 1.7 I don't need to use South or any other migration system, so I am just using simple command python manage.py makemigrations

However, all I get is this error:

You are trying to add a non-nullable field 'new_field' to userprofile without a default;
we can't do that (the database needs something to populate existing rows).

Here is models.py:

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    website = models.URLField(blank=True)
    new_field = models.CharField(max_length=140)

What are options?

Irmantas Želionis
  • 2,194
  • 3
  • 17
  • 30
  • 7
    I wanted to add that the problem occurs when you're changing existing table, not when you're creating a new one. – x-yuri May 18 '17 at 10:48

20 Answers20

131

If you are in early development cycle and don't care about your current database data you can just remove it and then migrate. But first you need to clean migrations dir and remove its rows from table (django_migrations)

rm  your_app/migrations/* 

Note: Don't delete _ _ init _ _ .py in the migrations folder.

rm db.sqlite3
python manage.py makemigrations
python manage.py migrate

If you previously created a superuser for Django's Admin web app then you might need to create the user again.

DaCruzR
  • 347
  • 2
  • 5
  • 14
Tomasz
  • 1,895
  • 1
  • 14
  • 17
  • 13
    One more thing. You need to clean up migrations table e.g.: `mysql -u[user] [database] -e "delete from django_migrations where app=[your_app]"` – helpse Dec 17 '15 at 19:18
  • This is the way. I think Django sucks at migration and model detection, etc. Want a major update for this. – WesternGun Mar 01 '18 at 10:31
  • I have deleted all files from migrations and deleted all rows from django_migrations and now I am getting "django.db.migrations.exceptions.NodeNotFoundError: Migration stories.0001_initial dependencies reference nonexistent parent node ('sources', '0002_auto_20180903_1224')" when running migration. – brainLoop Sep 07 '18 at 13:46
  • 3
    Also be sure you don't delete the `__init__.py` from migrations, or, you restore it afterwards, otherwise makemigrations won't work https://stackoverflow.com/a/46362750/1649917 – nmu Sep 09 '18 at 10:04
  • 1
    `python manage.py sqlmigrate name_of_your_app nb_of_the_migration` is also required – zar3bski Nov 26 '18 at 16:10
  • This is my go-to way whenever it is not obvious what field Django is talking about. Sometimes it complains about defaults on fields that are not present in the model. In that case, I just nuke the entire directory and respective rows in the `django_migrations` table. P.S. Obviously, this way is difficult to use when there is meaningful data to be preserved. In that case, it is a PIA. – MadPhysicist Jul 28 '20 at 10:27
130

You need to provide a default value:

new_field = models.CharField(max_length=140, default='SOME STRING')
dgel
  • 16,352
  • 8
  • 58
  • 75
  • What if I need to have new_field a copy of a website field. How that should look? `default = website` does not do the job – Irmantas Želionis Oct 03 '14 at 20:17
  • 14
    You would want to first do the migration with a bogus default value, then create a [data migration](https://docs.djangoproject.com/en/1.7/topics/migrations/#data-migrations) to iterate through each record and set `new_field` to `website`. – dgel Oct 03 '14 at 21:32
  • 1
    default should be optional for CharField – Florent Jan 21 '20 at 15:43
  • 2
    This doesn't really answer the question, since the question specifically states "without a default". – DragonBobZ Dec 01 '21 at 17:16
51

One option is to declare a default value for 'new_field':

new_field = models.CharField(max_length=140, default='DEFAULT VALUE')

another option is to declare 'new_field' as a nullable field:

new_field = models.CharField(max_length=140, null=True)

If you decide to accept 'new_field' as a nullable field you may want to accept 'no input' as valid input for 'new_field'. Then you have to add the blank=True statement as well:

new_field = models.CharField(max_length=140, blank=True, null=True)

Even with null=True and/or blank=True you can add a default value if necessary:

new_field = models.CharField(max_length=140, default='DEFAULT VALUE', blank=True, null=True)
Ian
  • 172
  • 1
  • 13
Tobi
  • 624
  • 4
  • 8
  • 8
    «Avoid using null on string-based fields such as CharField and TextField. If a string-based field has null=True, that means it has two possible values for “no data”: NULL, and the empty string.» —[Model field reference](https://docs.djangoproject.com/en/dev/ref/models/fields/#null) – Chema Oct 06 '17 at 07:47
24

In case anyone is setting a ForeignKey, you can just allow nullable fields without setting a default:

new_field = models.ForeignKey(model, null=True)

If you already have data stored within the database, you can also set a default value:

new_field = models.ForeignKey(model, default=<existing model id here>)
Justin Lange
  • 897
  • 10
  • 25
13

If you are early into the development cycle you can try this -

Remove/comment that model and all its usages. Apply migrations. That would delete that model and then add the model again, run migrations and you have a clean model with the new field added.

Harsh
  • 460
  • 5
  • 9
  • 1
    And clean up migrations table django_migrations as outlined here: https://stackoverflow.com/questions/26185687/you-are-trying-to-add-a-non-nullable-field-new-field-to-userprofile-without-a#comment56426466_30456675 Or just use a GUI and delete required rows. – ruslaniv Nov 30 '19 at 10:36
11

You can't add reference to table that have already data inside.
Change:

user = models.OneToOneField(User)

to:

user = models.OneToOneField(User, default = "")

do:

python manage.py makemigrations
python manage.py migrate

change again:

user = models.OneToOneField(User)

do migration again:

python manage.py makemigrations
python manage.py migrate
E. Kristiyono
  • 111
  • 2
  • 2
4

If "website" can be empty than new_field should also be set to be empty.

Now if you want to add logic on save where if new_field is empty to grab the value from "website" all you need to do is override the save function for your Model like this:

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    website = models.URLField(blank=True, default='DEFAULT VALUE')
    new_field = models.CharField(max_length=140, blank=True, default='DEFAULT VALUE')

    def save(self, *args, **kwargs):
        if not self.new_field:
            # Setting the value of new_field with website's value
            self.new_field = self.website

        # Saving the object with the default save() function
        super(UserProfile, self).save(*args, **kwargs)
MMayla
  • 199
  • 1
  • 14
Alex Carlos
  • 882
  • 5
  • 7
4

Here is a workaround without having to make compromises such as dropping all existing data/migrations (yikes), requiring two separate migrations, or setting an unwanted default. Take these steps:

  1. Add the new field to your model with null=True
  2. python manage.py makemigrations <app_name> --name <migration_name>
  3. Change the new field to null=False
  4. python manage.py makemigrations <app_name>. In this step, you'll see an option you may never have seen before! You want option 2: "Ignore for now, and let me handle existing rows with NULL myself (e.g. because you added a RunPython or RunSQL operation to handle NULL values in a previous data migration)" enter image description here
  5. Move the migrations.AlterField operation from the second migration into the first one, and add a manual migration to take care of the NULL values (if you don't take this step you'll get integrity errors like before), like so:
def initial_display_names(apps, schema):
    Player = apps.get_model('my_app', 'Player')
    Player.objects.all().update(display_name='Cool Name')

def reversal(*args):
    """Reversal is NOOP since display_name is simply dropped during reverse"""


class Migration(migrations.Migration):

    dependencies = [
        ('my_app', '0049_foo'),
    ]

    operations = [
        migrations.AddField(
            model_name='player',
            name='display_name',
            field=models.CharField(help_text='name as shown in the UI', max_length=256, null=True),
        ),
        migrations.RunPython(initial_display_names, reversal),
        migrations.AlterField(
            model_name='player',
            name='display_name',
            field=models.CharField(help_text='name as shown in the UI', max_length=256),
        ),
    ]
  1. Remove the second migration you made.
  2. python manage.py migrate <app_name>
Joey
  • 3
  • 2
DragonBobZ
  • 2,194
  • 18
  • 31
3

I was early in my development cycle, so this may not work for everyone (but I don't see why it wouldn't).

I added blank=True, null=True to the columns where I was getting the error. Then I ran the python manage.py makemigrations command.

Immediately after running this command (and before running python manage.py migrate), I removed the blank=True, null=True from all the columns. Then I ran python manage.py makemigrations again. I was given an option to just change the columns myself, which I selected.

Then I ran python manage.py migrate and everything worked well!

Joseph Gill
  • 1,067
  • 11
  • 18
2

In new_file add the boolean property null.

new_field = models.CharField(max_length=140, null=True)

after you run a ./manage.py syncdb for refresh the DB. and finally you run ./manage.py makemigrations and ./manage.py migrate

gerachev
  • 121
  • 1
  • 4
2

Do you already have database entries in the table UserProfile? If so, when you add new columns the DB doesn't know what to set it to because it can't be NULL. Therefore it asks you what you want to set those fields in the column new_fields to. I had to delete all the rows from this table to solve the problem.

(I know this was answered some time ago, but I just ran into this problem and this was my solution. Hopefully it will help anyone new that sees this)

MMayla
  • 199
  • 1
  • 14
Arnold Lam
  • 333
  • 3
  • 10
  • 1
    I haven't inserted rows into the table and still get this. I have to delete all migration history, clear migration table to change the model, as suggested by Tomasz. – WesternGun Mar 01 '18 at 10:33
2

You can use method from Django Doc from this page https://docs.djangoproject.com/en/1.8/ref/models/fields/#default

Create default and use it

def contact_default():
   return {"email": "to1@example.com"}

contact_info = JSONField("ContactInfo", default=contact_default)
1

I honestly fount the best way to get around this was to just create another model with all the fields that you require and named slightly different. Run migrations. Delete unused model and run migrations again. Voila.

Josh
  • 2,122
  • 1
  • 21
  • 28
1

If you are fine with truncating the table of the model in question, you can specify a one-off default value of None in the prompt. The migration will have superfluous default=None while your code has no default. It can be applied just fine because there's no data in the table anymore which would require a default.

jnns
  • 5,148
  • 4
  • 47
  • 74
0

What Django actually says is:

Userprofile table has data in it and there might be new_field values which are null, but I do not know, so are you sure you want to mark property as non nullable, because if you do you might get an error if there are values with NULL

If you are sure that none of values in the userprofile table are NULL - fell free and ignore the warning.

The best practice in such cases would be to create a RunPython migration to handle empty values as it states in option 2

2) Ignore for now, and let me handle existing rows with NULL myself (e.g. because you added a RunPython or RunSQL operation to handle NULL values in a previous data migration)

In RunPython migration you have to find all UserProfile instances with empty new_field value and put a correct value there (or a default value as Django asks you to set in the model). You will get something like this:

# please keep in mind that new_value can be an empty string. You decide whether it is a correct value.
for profile in UserProfile.objects.filter(new_value__isnull=True).iterator():
    profile.new_value = calculate_value(profile)
    profile.save() # better to use batch save

Have fun!

taras
  • 3,579
  • 3
  • 26
  • 27
  • I can't seem to find where this is written in the documentation. Can you post the link please – Cody Apr 04 '18 at 10:07
0

In models.py

class UserProfile(models.Model): user = models.OneToOneField(User) website = models.URLField(blank=True) new_field = models.CharField(max_length=140, default="some_value")

You need to add some values as default.

0

Basically I solved this Issue putting null=True in added model. For example:

I was trying to add phone_number in the existing database module.

phone_number = models.CharField(max_length=10)

I previously got this error:

You are trying to add a non-nullable field 'phone_number' to customer 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 with a null value for this column)
  2. Quit, and let me add a default in models.py

After putting

phone_number = models.CharField(max_length=10, null=True)

python manage.py makemigrations
Migrations for 'collegekhajagharapp':
  collegekhajagharapp\migrations\0002_customer_phone_number.py
    - Add field phone_number to customer
David Buck
  • 3,752
  • 35
  • 31
  • 35
  • 2
    Multiple earlier answers, including [this answer](https://stackoverflow.com/a/27036431) from 2014 already suggest using `null=True`. If you are going to answer old questions, please try not to post answers that are already given. – David Buck Apr 04 '21 at 14:49
0

Delete Model => Makemigrations Models => Migrate Models => Return Back the models => Makemigrations Models => Migrate Models

-1

If the SSH it gives you 2 options, choose number 1, and put "None". Just that...for the moment.

-2

If your table is new and you dont care about the data follow below steps:

  1. Delete FROM public.django_migrations where app=<your_app_name>
  2. Delete all migrations file from your project
  3. DROP table <your_table_name>
  4. python manage.py makemigrations
  5. python manage.py migrate

If you care about data, then add a default to your field

new_field = models.CharField(max_length=140, default='your_default_value')
ratnesh
  • 436
  • 1
  • 5
  • 16