4

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

案子:

核心/模型.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()

自定义/models.py

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

自定义是一个应用程序。

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

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

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

4

4 回答 4

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方法。虽然我认为如果您在运行迁移后更改城市模型可能会遇到问题,但它可能不会将您的数据移动到新表中,但我不确定这一点。

于 2019-08-29T22:44:18.860 回答
0

代理模型不添加新表。从您提到的文档链接

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. 文档部分多表继承中介绍了其工作原理(和示例)。

如果您想要一个单一的数据库表,那么您应该使用代理模型,但是它们确实不允许您创建新字段。该字段应该在父模型中创建,或者存在于数据库中,并且根本不由 Django 迁移处理。

于 2019-08-23T16:05:58.010 回答
0

您正在寻找抽象基类模型:

当您想将一些公共信息放入许多其他模型中时,抽象基类很有用。您编写基类并将 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 级别分解常见信息的方法,同时在数据库级别仍然为每个子模型创建一个数据库表

于 2019-08-23T16:13:38.123 回答
0

您可以在像这样定义之后更新或创建您的类常量

from core.models import City    

City.newfield = models.CharField(max_length=20)
于 2019-08-27T18:18:42.980 回答