user123892
user123892

Reputation: 1293

Django 1.8: Delete/rename a model field in data migration

I need to change the relationship of a model field from ForeignKey to ManyToManyField. This comes with a data migration, to update the pre-existing data.

The following is the original model (models.py):

class DealBase(models.Model):

    [...]
    categoria = models.ForeignKey('Categoria')
    [...]

    )

I need the model field 'categoria' to establish a many2many relationship with the model 'Categoria' in the app 'deal'.

What I did:

  1. Create a new field 'categoria_tmp' in DealBase

    class DealBase(models.Model):
         categoria = models.ForeignKey('Categoria')
         categoria_tmp = models.ManyToManyField('Categoria',related_name='categoria-temp')
    
  2. make a schema migration

    python manage.py makemigrations

  3. Edit the migrationfile.py to migrate data from categoria to categoria-tmp

    def copy_deal_to_dealtmp(apps, schema_editor):
        DealBase = apps.get_model('deal', 'DealBase')
    
        for deal in DealBase.objects.all():
            deal.categoria_tmp.add(deal.categoria)
            deal.save()
    
    class Migration(migrations.Migration):
    
        dependencies = [
          ('deal', '0017_dealbase_indirizzo'),
        ]
    
        operations = [
           migrations.AddField(
           model_name='dealbase',
           name='categoria_tmp',
           field=models.ManyToManyField(related_name='categoria-temp', to='deal.Categoria'),
           preserve_default=True,
          ),
    
           migrations.RunPython(
            copy_deal_to_dealtmp
           )
          ]
    
  4. make data migration

    python manage.py migrate

  5. Finally I need to delete the column 'dealbase.categoria' and rename the column 'dealbase.categoria-tmp' to 'dealbase.categoria'

I'm stuck at step 5.

Could someone help me out? I cannot find online an answer, I'm using Django 1.8.

Thanks!

Upvotes: 2

Views: 17319

Answers (3)

Fernando Cruz
Fernando Cruz

Reputation: 1

If you don't have any data in this model, just comment on that model, and then run manage.py makemigrations and migrate. Then delete the wrong field and delete the comment code, and make makemigrations and migrate. This also works in Django 2.

Upvotes: 0

Jeff_Hd
Jeff_Hd

Reputation: 2244

You just need to create two additional migrations: one to remove the old field and the other to alter the new field.

First remove dealbase.categoria and create a migration and then rename dealbase.categoria-tmp to dealbase.categoria and create another migration.

This will delete the first field and then alter the tmp field to the correct name.

Upvotes: 6

itzMEonTV
itzMEonTV

Reputation: 20349

Try this, may help you.

  1. Step 1 as yours

    python manage.py makemigrations && python manage.py migrate
    
  2. Open shell

    for i in DealBase.objects.all()
        i.categoria_tmp.add(i.categoria)
    
  3. Remove your field categoria

    python manage.py makemigrations && python manage.py migrate
    
  4. Add field

    categoria = models.ManyToManyField('Categoria',related_name='categoria-temp')
    

    Then

    python manage.py makemigrations && python manage.py migrate
    
  5. Open shell

    for i in DealBase.objects.all():
        for j in i.categoria_tmp.all():
            i.categoria.add(j)
    
  6. Remove field categoria_tmp

    python manage.py makemigrations && python manage.py migrate
    

Upvotes: 0

Related Questions