假设我创建了两个模型:
class Car(models.Model):
name = models.CharField(max_length=50)
size = models.IntegerField()
class Manufacturer(models.Model):
name = models.CharField(max_length=50)
country = models.CharField(max_length=50)
car = models.ManyToManyField(Car)
我在两个模型中添加了条目,然后我意识到每辆车只与一个独特的制造商有关。所以,我应该将ManyToManyField转换为ForeignKey:
class Car(models.Model):
name = models.CharField(max_length=50)
size = models.IntegerField()
manufacturer = models.ForeignKey(Manufacturer)
class Manufacturer(models.Model):
name = models.CharField(max_length=50)
country = models.CharField(max_length=50)
如何在不丢失参赛作品的情况下做到这一点?我试着查看南方文档,但我没有找到这种转换方式......
答案 0 :(得分:7)
这非常重要,我认为您需要进行三次迁移:
ForeignKey
。ManyToMany
转换为ForeignKey
(使用forwards
方法)。ManyToMany
。你可以将1和2或2和3合并在一起,但我不推荐它
此外,您还应该为2实现backwards
方法。
2. forwards
的示例将是:
class Migration(SchemaMigration):
def forwards(self, orm):
for manufacturer in orm.Manufacturer.objects.all():
for car in manufacturer.car.all():
car.manufacturer = manufacturer
car.save()
请注意:
backwards
方法。您还需要在步骤2. / 3中更新使用这些关系的代码。
答案 1 :(得分:5)
根据Thomas Orozco提供的优秀答案,我想为Django> = 1.7提供解决方案(基本上,第2点将ManyToMany转换为ForeignKey 是新的变化Django的版本)。所以这里是第二次迁移的代码:
class Migration(migrations.Migration):
def migrate_m2m_to_fk(apps, schema_editor):
Manufacturer = apps.get_model("app", "Manufacturer")
for manufacturer in Manufacturer.objects.all():
for car in manufacturer.car.all():
car.manufacturer = manufacturer
car.save()
def migrate_fk_to_m2m(apps, schema_editor):
Car = apps.get_model("app", "Car")
for c in Car.objects.all():
if c.manufacturer:
c.manufacturer.car.add(c)
c.manufacturer.save()
operations = [
migrations.RunPython(migrate_m2m_to_fk, migrate_fk_to_m2m)
]
其中" app"是模型所在的Django应用程序。显示了正向和反向迁移代码(正如托马斯所提到的,如果预先存在多个关系,运行此迁移可能会导致数据丢失,所以请注意)。