Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django migrations changing choices value

Tags:

mysql

django

A field has been added to one of my MySQL table previously:

# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2017-09-14 00:49
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('my_app', '0102_previous_migrations'),
    ]

    operations = [
        migrations.AddField(
            model_name='my_client',
            name='my_team',
            field=models.CharField(choices=[('Unassigned', 'Unassigned'), ('ACT', 'ACT'), ('Korea', 'Korea'), ('National', 'National')], default='Unassigned', max_length=255, verbose_name='My Team'),
        ),
    ]

So users have a choices of the above selection in my UI and will be saved into the table my_client:

  • Unassigned
  • ACT
  • Korea
  • National

The changes have been deployed and now a beginner like me would like to change, i.e. remove Korea and add 2 new choices: NSW and SA

How would I go about this? Do I need another migration or I will just need to change those choices in the models?

I use this in my model now like this:

class Client(MyAppModel):
    TEAM_CHOICES = (
        ('Unassigned', 'Unassigned'),
        ('ACT', 'ACT'),
        ('Korea', 'Korea'),
        ('National', 'National'),
)

DEFAULT_TEAM = 'Unassigned'
my_team = models.CharField(verbose_name='MyTeam', null=False, max_length=255, choices=TEAM_CHOICES, default=DEFAULT_TEAM)

Update:

Base on the comment I have, I will need a migration too, a AlterField?

Do I also have to update all the existing value right now in the table my_client if any of them is having Korea to say Unassigned if I would like to remove Korea as a choice? What command can I use in the migration?

like image 367
Steven Yong Avatar asked Oct 26 '17 02:10

Steven Yong


1 Answers

Figure this out later, hope it helps others beginner like me.

I have to update the Client model

class Client(MyAppModel):
    TEAM_CHOICES = (
        ('Unassigned', 'Unassigned'),
        ('National', 'National'),
        ('NSW', 'NSW'),
        ('SA', 'SA'),
)

Then enter this command:

python manage.py makemigrations

A migration will be generated:

from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('my_app', '0102_previous_migrations'),
    ]

    operations = [
        migrations.AlterField(
            model_name='my_client',
            name='my_team',
            field=models.CharField(choices=[('Unassigned', 'Unassigned'), ('ACT', 'ACT'), ('National', 'National'), ('NSW', 'NSW'), ('SA', 'SA')], default='Unassigned', max_length=255, verbose_name='My Team'),
        ),
    ]

Next to update all the existing values in the table now, referred here, enter this command to create an empty migration file:

python manage.py makemigrations --empty my_app

In the new migration file, put something like:

# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2017-10-26 06:36
from __future__ import unicode_literals

from django.db import migrations

def set_unassigned(apps, schema_editor):
    Client = apps.get_model('my_app', 'my_client')
    for client in Client.objects.all():
        client.account_team = 'Unassigned'
        client.save()

class Migration(migrations.Migration):

    dependencies = [
        ('my_app', '0104_client_team_update'),
    ]

    operations = [
        migrations.RunPython(set_unassigned),
    ]
like image 150
Steven Yong Avatar answered Nov 14 '22 22:11

Steven Yong