Django将现有字段更改为外键。

5

我有一个 Django 模型,它以前是这样的:

class Car(models.Model):
    manufacturer_id = models.IntegerField()

有另一个模型叫做Manufacturer,它的id字段是指向它的。然而,我意识到使用Django内置的外键功能会很有用,所以我将模型更改为以下内容:
class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer)

这个改变似乎立即生效,查询无错误,但当我尝试运行迁移时,Django输出如下内容:
- Remove field manufacturer_id from car
- Add field manufacturer to car

进行这种迁移将清除数据库中的所有现有关系,所以我不想这样做。实际上,我根本不希望进行任何迁移,因为像Car.objects.get(manufacturer__name="Toyota")这样的查询工作得很好。我希望有一个适当的数据库外键约束,但这不是一个高优先级的问题。

所以我的问题是:有没有一种方法可以通过迁移或其他方式将现有字段转换为外键?我不能使用--fake,因为我需要可靠地在开发、生产和同事们的计算机上正常工作。

2个回答

7

您可以进行数据迁移

  1. 添加一个新字段
  2. 进行数据迁移 https://docs.djangoproject.com/en/3.1/topics/migrations/#data-migrations
  3. 删除旧字段

我不确定,可能有另一种解决方案,您可以将字段重命名为所需的名称,然后修改字段类型 (执行迁移)

operations = [
        migrations.RenameField(
            model_name='car',
            old_name='manufacturer_id',
            new_name='manufacturer',
        ),
        migrations.AlterField(
            model_name='car',
            name='manufacturer',
            field=ForeignKey(blank=True, null=True,  
                  on_delete=django.db.models.deletion.CASCADE
            ),
    ]

-1

今天我也遇到了同样的问题。 可以在不重命名现有字段或删除现有列的情况下完成。

  1. 使用CreateModel操作更新初始迁移
...
        migrations.CreateModel(
            name="Car",
            fields=[
                (
                    "manufacturer",
                    models.ForeignKey(
                        blank=True,
                        null=True,
                        on_delete=django.db.models.deletion.DO_NOTHING,
                        db_constraint=False,
                        db_index=False,
                        to="Manufacturer",
                    ),
                ),
  1. 检查 Car 模型的 Car.manufacturer 字段上的 db_constraintdb_index 是否为 True。如果未设置,则 True 是默认值。
  2. 运行 ./manage.py makemigrations 命令,生成带有所需约束和索引的 AlterField 迁移,用于 Car.manufacturer_id 字段。

第一步不会影响数据库的一致性,因为对于具有 db_constaint=Falsedb_index=FalseIntegerFieldForeignKey,生成的 DDL 将是相同的。

第二个迁移将添加缺失的约束和索引。

您可以使用 ./manage.py sqlmigrate app migration 命令进行检查。


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