将 Django 模型字段的类型从 CharField 更改为 ForeignKey [英] Change type of Django model field from CharField to ForeignKey

查看:34
本文介绍了将 Django 模型字段的类型从 CharField 更改为 ForeignKey的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将我的一个 Django 模型中的字段类型从 CharField 更改为 ForeignKey.这些字段已经填充了数据,所以我想知道最好或正确的方法是什么.我可以只更新字段类型并迁移,还是有任何可能的陷阱"需要注意?注意:我只使用 vanilla Django 管理操作(makemigrationsmigrate),而不是 South.

I need to change the type of a field in one of my Django models from CharField to ForeignKey. The fields are already populated with data, so I was wondering what is the best or right way to do this. Can I just update the field type and migrate, or are there any possible 'gotchas' to be aware of? N.B: I just use vanilla Django management operations (makemigrations and migrate), not South.

推荐答案

这很可能是您想要进行多阶段迁移的情况.我对此的建议如下所示.

This is likely a case where you want to do a multi-stage migration. My recommendation for this would look something like the following.

首先,假设这是您的初始模型,在名为 discography 的应用程序中:

First off, let's assume this is your initial model, inside an application called discography:

from django.db import models

class Album(models.Model):
    name = models.CharField(max_length=255)
    artist = models.CharField(max_length=255)

现在,您意识到您想为艺术家使用 ForeignKey.好吧,如前所述,这不仅仅是一个简单的过程.它必须分几个步骤完成.

Now, you realize that you want to use a ForeignKey for the artist instead. Well, as mentioned, this is not just a simple process for this. It has to be done in several steps.

第一步,为 ForeignKey 添加一个新字段,确保将其标记为 null:

Step 1, add a new field for the ForeignKey, making sure to mark it as null:

from django.db import models

class Album(models.Model):
    name = models.CharField(max_length=255)
    artist = models.CharField(max_length=255)
    artist_link = models.ForeignKey('Artist', null=True)

class Artist(models.Model):
    name = models.CharField(max_length=255)

...并为此更改创建迁移.

...and create a migration for this change.

./manage.py makemigrations discography

第 2 步,填充新字段.为此,您必须创建一个空迁移.

Step 2, populate your new field. In order to do this, you have to create an empty migration.

./manage.py makemigrations --empty --name transfer_artists discography

一旦你有了这个空迁移,你想添加一个 RunPython 操作到它以链接你的记录.在这种情况下,它可能看起来像这样:

Once you have this empty migration, you want to add a single RunPython operation to it in order to link your records. In this case, it could look something like this:

def link_artists(apps, schema_editor):
    Album = apps.get_model('discography', 'Album')
    Artist = apps.get_model('discography', 'Artist')
    for album in Album.objects.all():
        artist, created = Artist.objects.get_or_create(name=album.artist)
        album.artist_link = artist
        album.save()

现在您的数据已传输到新字段,您实际上可以完成并保留所有内容,将新字段用于所有内容.或者,如果你想做一些清理工作,你想再创建两个迁移.

Now that your data is transferred to the new field, you could actually be done and leave everything as is, using the new field for everything. Or, if you want to do a bit of cleanup, you want to create two more migrations.

对于您的第一次迁移,您需要删除原始字段 artist.对于您的第二次迁移,将新字段 artist_link 重命名为 artist.

For your first migration, you will want to delete your original field, artist. For your second migration, rename the new field artist_link to artist.

这是在多个步骤中完成的,以确保 Django 正确识别操作.您可以手动创建迁移来处理此问题,但我会让您自己弄清楚.

This is done in multiple steps to ensure that Django recognizes the operations properly. You could create a migration manually to handle this, but I will leave that to you to figure out.

这篇关于将 Django 模型字段的类型从 CharField 更改为 ForeignKey的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆