pythondjangodjango-2.0

Migrating problems when porting Django project to Python 3 and Django 2


I've been porting a Django project to Python 3 and Django 2. I have had to add on_delete to all my models with foreign keys as required in Django 2. Now I have tried to make migrations for those changes have been getting TypeError: __init__() missing 1 required positional argument: 'on_delete'.

The file it references is the 0002 migration file not the models file which has been updated. I am not sure how to go about fixing this. I have tried faking the migrations and I still get the same error.

I am not sure why it thinks the database doesn't exist, I have checked and everything is intact and working in Postgres. Any ideas?


Solution

  • Since ForeignKey fields [Django-doc] and OneToOneField fields fields now have a required on_delete parameter.

    This is specified in the release notes of Django-2.0 under Features removed in 2.0:

    The on_delete argument for ForeignKey and OneToOneField is now required in models and migrations. Consider squashing migrations so that you have fewer of them to update.

    You thus should inspect your migration files for ForeignKeys and OneToOneFields, and add an on_delete parameter, like:

    class Migration(migrations.Migration):
    
        initial = False
    
        dependencies = [
            ('app', '0001_initial'),
        ]
    
        operations = [
            migrations.CreateModel(
                name='Model',
                fields=[
                    ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                    ('some_foreignkey', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.OtherModel')),
                ],
            ),
        ]

    You should inspect the documentation on the on_delete parameter to see what deletion strategy is the best for each situation. The options are, at the time of writing CASCADE, PROTECT, SET_NULL, SET_DEFAULT, SET(..), DO_NOTHING.

    If you did not specify the on_delete in the pre- versions, it made a default to CASCADE. So if you want the same behavior, you should add on_delete=models.CASCADE. This is noted in the 1.11 version of the documentation on on_delete:

    Deprecated since version 1.9: on_delete will become a required argument in Django 2.0. In older versions it defaults to CASCADE.