2

So I have a model in my Django project (for arguments sake called 'app'), for example;

class ModelA(models.Model):
    fieldA = models.IntegerField(default=0)

and I can run python manage.py makemigrations app; which gives me

Migrations for 'app':
  app/migrations/0001_initial.py
    - Create model ModelA

If I then add a new field to ModelA so it looks like;

class ModelA(models.Model):
    fieldA = models.IntegerField(default=0),
    fieldB = models.IntegerField(default=1)

and then run makemigrations again, I get;

Migrations for 'app':
  app/migrations/0002_auto_20170529_1737.py
    - Remove field fieldA from modela
    - Add field fieldB to modela

The auto-generated file backs this up;

operations = [
        migrations.RemoveField(
            model_name='modela',
            name='fieldA',
        ),
        migrations.AddField(
            model_name='modela',
            name='fieldB',
            field=models.IntegerField(default=1),
        ),
    ]

Why does it remove fieldA?

My understanding was that it should only script changes to the models, i.e. That fieldB has been added.

cgt_mky
  • 196
  • 1
  • 2
  • 7

2 Answers2

10

The problem is that you added a comma to the fielda line when you added fieldb:

fieldA = models.IntegerField(default=0),

You should remove the comma and delete the 0002 migration. Then, when you rerun makemigrations, Django will no longer try to remove fielda.

Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • 1
    *facepalm* Thank you, very much! That was so frustrating. – cgt_mky May 29 '17 at 18:00
  • 2
    4 years and a half later, this answer is still relevant and saved me from falling to alcohol and slowly go to live under a bridge. Thank you sir. – pmourelle Nov 12 '21 at 02:58
2

I do not see the whole class that countains your field but it appears that a field can be omitted or removed from the migration process if there is a @property method with the same name as your field. The code below will thus remove fieldA from the database

class ModelA(models.Model):
    fieldA = models.IntegerField(default=0)

    @property
    def fieldA(self):
        pass

and you should rename your field or your method :

class ModelA(models.Model):
    _fieldA = models.IntegerField(default=0)

    @property
    def fieldA(self):
        pass 
David
  • 492
  • 8
  • 17