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

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

问题描述

我需要将我的Django模型之一中的字段类型从 CharField 更改为 ForeignKey .这些字段已经填充了数据,所以我想知道什么是最好的或正确的方法.我可以仅更新字段类型并进行迁移,还是要注意任何可能的陷阱"? NB :我只使用普通的Django管理操作( makemigrations migrate ),而不是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.

第1步,为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天全站免登陆