I think I have a more or less unorthodox and hackish question for you. What I currently have is django project with multiple apps. I want to use a non-abstract model (ModelA)
of one app (app1
) and use it in another app (app2
) by subclassing it. App1's models should not be migrated to the DB, I just want to use the capabilities of app1 and it's model classes, by extending its functionality and logic. I achieved that by adding both apps to settings.INSTALLED_APPS
, and preventing app1's models being migrated to the DB.
我想我或多或少有一个非正统和黑客的问题。我目前拥有的是具有多个应用程序的django项目。我想使用一个应用程序(app1)的非抽象模型(ModelA),并通过继承它在另一个应用程序(app2)中使用它。 App1的模型不应该迁移到DB,我只想通过扩展其功能和逻辑来使用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://*.com/a/35921487/1230358
MIGRATION_MODULES = {
'App1': None,
}
So far so good, ugly and hackish, I know... The remaining problem is now that most of app1's models are non-abstract (ModelA) and if I try to subclass them, none of the ModelA's fields get populated to the db into the table named app2_modelb
. This is clear to me, because I excluded the App1 from migrating to the DB and therefore the table app1_modela is completely missing in the DB.
到目前为止,这么好,丑陋和hackish,我知道......剩下的问题是,现在大多数app1的模型都是非抽象的(ModelA),如果我尝试将它们子类化,那么ModelA的所有字段都不会填充到db中名为app2_modelb的表。这对我来说很清楚,因为我将App1排除在迁移到数据库之外,因此数据库中的表app1_modela完全丢失。
My idea now was to clone ModelA, preserve all its functionallity, and changing it's Meta information from non-abstract to abstract (ModelB.Meta.abstract = True
). I hope that by this, all the original fields of ModelA will be inherited to ModelB and can be found in its respective DB table and columns (app1_modelb
).
我现在的想法是克隆ModelA,保留其所有功能,并将其元信息从非抽象更改为抽象(ModelB.Meta.abstract = True)。我希望通过这种方式,ModelA的所有原始字段都将继承到ModelB,并且可以在其各自的DB表和列(app1_modelb)中找到。
What I have right now is:
我现在拥有的是:
# 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
My current way (pseudo code) to make an existing non-abstract model abstract looks like this:
我现有的非抽象模型抽象方式(伪代码)如下所示:
# 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)
This does not work, and after this lengthy description my (simple) question would be, if and how is it possible to clone a non-abstract model class preserving all its functionality and how to change it to be abstract?
这不起作用,在这个冗长的描述之后我的(简单)问题是,是否可以克隆非抽象模型类,保留其所有功能以及如何将其更改为抽象?
Just to be clear. All upper fuzz is about, that I can't change any code in app1. May it be that app1 is a django app installed via pip.
只是要清楚。所有上层模糊都是关于,我无法更改app1中的任何代码。可能是app1是通过pip安装的django应用程序。
1 个解决方案
#1
0
Why not, in app1
为什么不,在app1
AbstractBaseModelA(models.Model):
# other stuff here
class Meta:
is_abstract=True
ModelA(AbstractBaseModelA):
# stuff
in app2:
在app2中:
MobelB(AbstractBaseModelA):
# stuff
Sorry if I've misunderstood your aims, but I think the above should achieve the same end result.
对不起,如果我误解了你的目标,但我认为上面应该达到同样的最终结果。
#1
0
Why not, in app1
为什么不,在app1
AbstractBaseModelA(models.Model):
# other stuff here
class Meta:
is_abstract=True
ModelA(AbstractBaseModelA):
# stuff
in app2:
在app2中:
MobelB(AbstractBaseModelA):
# stuff
Sorry if I've misunderstood your aims, but I think the above should achieve the same end result.
对不起,如果我误解了你的目标,但我认为上面应该达到同样的最终结果。