Django更新枚举表的行

时间:2016-05-15 22:02:00

标签: django database django-models enums

让我们说我有一个看起来像这样的枚举表(我知道它没有任何意义,但它现在不相关:)):

class Pet:
    ANIMALS = (
        ('D', 'Dog'),
        ('C', 'Cat'),
    )
    pet = models.CharField(primary_key=True, choices=ANIMALS)

    ...

让我们说我在另一个使用Pet类的表中创建了一些行。

如果在某些时候我决定我需要改变(' D',#39; Dog')到(' S',' Snake&# 39;)Django将自动检测包含' Dog'并更新它们?

2 个答案:

答案 0 :(得分:0)

不幸的是,Django不会自动执行此操作。您需要定义数据库迁移以更改宠物列中的数据,以及#34; D"到" S"。

以下是指向该部分文档的直接链接: https://docs.djangoproject.com/en/1.9/topics/migrations/#data-migrations

您的用例类似于Django提供的示例。在您的迁移文件中,您应该能够遍历所有Pet对象并更改每个实例上的pet属性,从" D"到" S"。

以下是未经测试的,但可能是进行此更改的起点。

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

def change_pet_key(apps, schema_editor):
    # We can't import the Pet model directly as it may be a newer
    # version than this migration expects. We use the historical version.
    Pet = apps.get_model("yourappname", "Pet")
    for pet in Pet.objects.all():
        pet.pet = 'S'
        pet.save()

class Migration(migrations.Migration):
    initial = True

    dependencies = [
        ('yourappname', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(change_pet_key),
    ]

答案 1 :(得分:0)

首先,您的模型存在一些问题。它不会继承自models.Model。并且选择了一个' field不是一个好的主键候选者。如果是,你的表中只能有两条记录。所以你的模型应该是

class Pet(models.Model):
    ANIMALS = (
        ('D', 'Dog'),
        ('C', 'Cat'),
    )
    pet = models.CharField(max_length=2, choices=ANIMALS)

你最好在这里使用int。

  Django将自动检测到行(' D',#39; Dog')(' S',#39; Snake')   包含' Dog'并更新它们?

没有。它将创建迁移,但迁移不会更改数据。如果要更改旧数据,只需键入./manage.py shell以打开控制台,然后执行DO

 from myapp.models import Pet
Pet.objects.filter(pet='D').update(pet='S')

请注意,循环遍历Pet.objects.all()并逐个更新它们并不高效。