从抽象模型迁移到代理模型

时间:2016-07-28 12:17:26

标签: django

现在,我有一个抽象模型,其中包含几个继承其字段的模型。但我发现了代理模型的强大功能,我想将它们应用到我的应用程序中。这是从现在起的照片:

class BaseModel(models.Model):
    field_1 = models.CharField(max_length=10)
    field_2 = models.CharField(max_length=10)
    field_3 = models.CharField(max_length=10)

    class Meta:
        abstract = True

class Model1(BaseModel):
    pass

    def __unicode__(self):
        return self.field_1

class Model2(BaseModel):
    pass

    def __unicode__(self):
        return self.field_1

这就是我想要的:

class BaseModel(models.Model):
    field_1 = models.CharField(max_length=10)
    field_2 = models.CharField(max_length=10)
    field_3 = models.CharField(max_length=10)

class Model1(BaseModel):
    pass

    class Meta:
        proxy = True

    def __unicode__(self):
        return self.field_1

class Model2(BaseModel):
    pass

    class Meta:
        proxy = True

    def __unicode__(self):
        return self.field_1

问题是当我删除“abstract = True”句子时。当我尝试迁移时,这是警告:

  

你试图在没有默认值的情况下向Model1添加一个不可为空的字段“basemodel_ptr”;我们不能这样做(数据库需要填充现有行的东西)。

好的,明白了。我读到“ptr”是一个指向父模型的指针,它是BaseModel,但是我没有任何BaseModel,在迁移之前我无法得到它。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

此次迁移并非易事。

目前,您的数据库有两个表:

  • yourapp_model1
  • yourapp_model2

两者都有相同的列,但它们使用不同的序列,这意味着它们的主键发生冲突:两个表都将从1开始计算它们的ID(也就是PK)。很可能存在Model1 pk=1的实例以及Model2 pk=1的实例,而且不是一样。

这是具有抽象模型和具体实现的要点:在分离数据库中的数据时共享Django代码(业务逻辑)。例如,因为它在语义上是不同的(不同类型)。

代理点模型完全相反:虽然数据位于数据库中的一个表中,但代理模型允许您实现不同的行为,但基于相同的数据库数据。

如果您现在从抽象模型迁移到代理模型,则意味着您曾经认为不同类型的内容现在将成为相同的类型(从数据库的角度来看)。如开头所述,您必须将数据从多个表移动到一个表中,并为至少部分表重新生成ID。也就是说,当前使用这些URL的那部分资源将改变/停止存在/指向不同的资源。

除非您可以从头开始(没有必须支持的实时数据),否则您应该非常感谢这种变化的重要性。

您是否需要支持实时数据:

  1. 删除数据库
  2. 重新创建数据库
  3. 删除所有迁移文件
  4. 从头开始重新创建所有迁移文件
  5. call migrate
  6. 实时数据的数据迁移:

    请注意,还有其他方法可以执行此操作。搜索" Django数据迁移"。

    1. 使用新名称(无碰撞)创建新的模型结构
    2. makemigrations现在将获取新的模型结构,并在数据库中创建新的和空的表,使旧表及其数据不受影响
    3. 创建一个管理命令,读取旧模型实例并将它们复制到新表中
    4. 一旦在生产中运行此命令,您可以弃用旧模型并删除它们,同时确保依赖于它们的所有内容现在都使用新表