【发布时间】:2017-03-15 12:39:45
【问题描述】:
我想我有一个或多或少的非正统和骇人听闻的问题要问你。我目前拥有的是具有多个应用程序的 django 项目。
我想使用一个应用程序的non-abstract model (ModelA) (app1) 并通过子类化它在另一个应用程序 (app2) 中使用它。 App1的模型
不应该迁移到数据库,我只想通过扩展其功能和逻辑来使用 app1 及其模型类的功能。
我通过将这两个应用程序添加到 settings.INSTALLED_APPS 并阻止将 app1 的模型迁移到数据库来实现这一点。
INSTALLED_APPS += (
'App1',
'App2',
)
# This is needed to just use App1's models
# without creating it's database tables
# See: http://stackoverflow.com/a/35921487/1230358
MIGRATION_MODULES = {
'App1': None,
}
到目前为止,一切都很好,丑陋和骇人听闻,我知道...剩下的问题是现在 app1 的大多数模型都是非抽象的 (ModelA),如果我尝试
为了对它们进行子类化,ModelA 的所有字段都不会填充到数据库中名为app2_modelb 的表中。这对我来说很清楚,因为我排除了 App1
迁移到数据库,因此数据库中完全缺少表 app1_modela。
我现在的想法是克隆 ModelA,保留其所有功能,并将其元信息从非抽象更改为抽象 (ModelB.Meta.abstract = True)。
我希望通过这种方式,ModelA的所有原始字段都将继承给ModelB,并且可以在其各自的DB表和列中找到(app1_modelb)。
我现在拥有的是:
# In app1 -> models.py
class ModelA(models.Model):
title = models.CharField(_('title'), max_length=255)
subtitle = models.CharField(_('subtitle'), max_length=255)
class Meta:
abstract = False # just explicitly for demonstration
# In app2 -> models.py
from app1.models import ModelA
class ModelB(ModelA):
pass
# Just extending ModelAdoes not create the fields title and subtitle fields in app2_modelb
# because ModelA.meta.abstract = False
我目前使现有非抽象模型抽象的方式(伪代码)如下所示:
# In app2 -> models.py
from app1.models import ModelA
def get_abstract_class(cls):
o = dict(cls.__dict__)
o['_meta'].abstract = True
o['_meta'].app_label = 'app2'
o['__module__'] = 'app2.models'
#return type('Abstract{}'.format(cls.__name__), cls.__bases__, o)
return type('Abstract{}'.format(cls.__name__), (cls,), o)
ModelB = get_abstract_class(ModelA)
class ModelC(ModelB):
# title and subtitle are inherited from ModelA
description = models.CharField(_('description'), max_length=255)
这不起作用,经过冗长的描述,我的(简单)问题是,是否以及如何克隆保留其所有功能的非抽象模型类以及如何将其更改为抽象?
只是为了清楚。所有上面的模糊都是关于,我无法更改 app1 中的任何代码。可能app1是通过pip安装的django应用。
【问题讨论】:
-
您是否打算禁止某人创建 ModelA 的实例?由于无论如何您都在走 hacky 路线,因此如果模型保存方法是调用它的 ModelA 类,您总是会在模型保存方法中引发错误...
-
您会添加任何新字段吗?
-
意图如下。假设我想重用 django-blog 应用程序的一些模型(app1 和 ModelA),我发现它们对我的物品(app2)非常有用。遗憾的是 app1.model.ModelA 不是抽象的,因为在 django-blog 应用程序中,它不需要是抽象的,因为在 app1 内部它是一个最终模型类。如果我想在我的应用程序 (app2) 中使用它,它必须是抽象的,以便我可以对它进行子类化,并且在表 (app2_modelb) 中生成所有字段(也是 ModelA 的字段)。总而言之,它是关于重用原本不打算重用的非抽象模型。
-
@SardorbekImomaliev,没有字段更改。模型应该保持不变,但要抽象。
-
@SardorbekImomaliev,很抱歉造成误解!我必须向子类添加字段。应该像最后一个代码块中的 ModelC。
标签: python django django-models