继承模型更新为其父模型

时间:2019-08-21 14:25:05

标签: python django django-inheritance

我需要从另一个模型扩展一个模型。

案例:

core / models.py

class Master(models.Model):
    code = models.CharField(max_length=30, unique=True)
    name = models.CharField(max_length=100, blank=False, null=False)

    class Meta:
        abstract = True

class City(Master):
        zipcode = models.IntegerField()

custom / models.py

from core.models import City
class City(City)
    newfield = models.CharField(max_length=20)

custom是一个应用。

我尝试使用代理模型,但这不是我所需要的,因为代理模型添加了一个新表。 https://docs.djangoproject.com/en/2.2/topics/db/models/#proxy-models

我需要的是,当我迁移时,将新字段添加到City。

  

更多信息。   在核心中,将创建表,而在定制中,您可以添加客户端需要的新字段。这个想法是核心只作为标准维护。

4 个答案:

答案 0 :(得分:0)

代理模型不添加新表。来自docs link you mentioned

  

MyPerson类与其父Person类在同一数据库表上操作。

如果您要一个叫core_city的表,而另一个叫custom_city的表,而第二个表有一个额外的字段,则只需将其子类化即可。也许使用别名会更容易:

from core.models import City as CoreCity

class City(CoreCity):
    newfield = models.CharField(max_length=20)

custom_city将包含core_city中的所有字段以及一个newfield。文档部分Multi-table inheritance中介绍了该方法的工作原理(以及示例)。

如果您要拥有一个单个数据库表,则应该使用代理模型,但是它们实际上不允许您创建新字段。该字段应在父模型中创建,否则应存在于数据库中,而根本不能由Django迁移处理。

答案 1 :(得分:0)

您正在寻找Abstract base classes型号:

  

当您要将一些公共信息放入许多其他模型中时,抽象基类很有用。您编写基类,并将abstract = True放入Meta类。

这是基类:

#core/models.py
class City(Master):
    zipcode = models.IntegerField()
    class Meta:
        abstract = True   # <--- here the trick

这里是您的模型:

#custom/models.py
from core.models import City as CoreCity
class City(CoreCity):
    newfield = models.CharField(max_length=20)
  

对于许多用途,这种类型的模型继承将正是您想要的。它提供了一种在Python级别上排除常见信息的方法,同时仍然仅在数据库级别为每个子模型创建一个数据库表

答案 2 :(得分:0)

您可以在定义了此类后更新或创建类常量

from core.models import City    

City.newfield = models.CharField(max_length=20)

答案 3 :(得分:0)

您可能需要使用可交换模型,使用它们可以定义City类并使用以后需要的任何模型进行更改, 但是那样一来,您将无法直接导入和使用基本City模型,则可能需要为此提供诸如get_city_model之类的方法作为公共API。

class City(Master):
    zipcode = models.IntegerField()

    class Meta:
        swappable = 'CORE_CITY_MODEL'

,也许以后再用其他模型替换它,然后以“ app_name.model_name”的形式将CORE_CITY_MODEL设置为该模型。

django.contrib.auth是一个很好的例子,您可以考虑检查User模型和get_user_model方法。尽管我认为如果在运行迁移后更改城市模型可能会遇到问题,但它可能不会将数据移到新表中,但是我不确定。