我需要从另一个模型扩展一个模型。
案例:
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。
更多信息。 在核心中,将创建表,而在定制中,您可以添加客户端需要的新字段。这个想法是核心只作为标准维护。
答案 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
方法。尽管我认为如果在运行迁移后更改城市模型可能会遇到问题,但它可能不会将数据移到新表中,但是我不确定。