Django迁移更改选择值

8

我之前的MySQL表中添加了一个字段:

# -*- 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'),
        ),
    ]

在我的用户界面中,用户可以选择上述选项之一,并将其保存到my_client表中:

  • 未分配
  • ACT
  • 韩国
  • 国家

更改已经部署,现在像我这样的初学者想要进行更改,即删除“韩国”并添加2个新选项:“NSW”和“SA”。

我该如何操作?我需要另一个迁移还是只需更改模型中的这些选项?

我现在在我的模型中使用它,就像这样:

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)

更新:

根据我的评论,我还需要进行迁移,使用AlterField命令吗?

如果我想将韩国从选择中删除,那么现在必须立即更新表my_client中所有已有的值,如果它们中有任何一个是Korea,则将其更新为“未分配”。在迁移中可以使用什么命令?


1
你需要进行迁移。请参考 https://stackoverflow.com/questions/33514058/django-creates-pointless-migrations-on-choices-list-change/33514551#33514551。 - solarissmoke
谢谢@solarissmoke,如果不显示变化只是选项的话,迁移会是什么样子? - Steven Yong
它应该只显示不断变化的选项。你的看起来是什么样子的? - solarissmoke
2个回答

4
希望这篇文章能帮助像我一样的初学者。需要更新客户端模型。
class Client(MyAppModel):
    TEAM_CHOICES = (
        ('Unassigned', 'Unassigned'),
        ('National', 'National'),
        ('NSW', 'NSW'),
        ('SA', 'SA'),
)

然后输入以下命令:

python manage.py makemigrations

将会生成一个迁移:
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'),
        ),
    ]

现在,要更新表中所有现有的值,请参考此处,输入以下命令创建一个空迁移文件:

python manage.py makemigrations --empty my_app

在新的迁移文件中,可以添加类似以下内容:

# -*- 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),
    ]

4

一种高层次的方法:

创建一个仅添加新选项的迁移。编写一个使用migration.RunPython方法来将所有具有旧选项的模型赋予适当的新选项的方法。创建一个删除旧选项的迁移。


你甚至可以将第二个迁移的 migrations.AlterField 操作提取出来,删除该迁移文件(如果它只包含该操作),将该操作放入第一个迁移文件中,并在其中间加入 RunPython 函数。这样,你就只有一个包含整个更改过程的迁移文件了。 - onekiloparsec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接