我想创建一个可以与其他应用程序一起使用的Foo应用程序,其他应用程序可以从Foo应用程序“继承”模型,视图和模板。
我正在为通用foos制作一个Django应用程序。 80%的时间,通用Foo
(和相关)模型足以存储数据,而另外20%的时间,简单的多表继承就足以扩展通用模型。但是,99%的情况下,通用视图是不够的,foo的 type 将确定哪个视图用于foo和与之相关的所有模型。新的foo类型基本上是每次我获得一个新客户端时都存在的,所以我必须将业务逻辑保存在不同的应用程序中。[1]
请注意,我的所有模型都与Foo
模型相关,如下所示:
from django.db import models
class Foo(models.Model):
# ... model fields and generic business logic
class Bar(models.Model):
foo = models.ForeignKey(Foo)
# ... other model fields and generic business logic
class Baz(models.Model):
bar = models.ForeignKey(Bar)
# ... other model fields and generic business logic
Foo
模型将包含应用程序的字符串名称,该名称包含描述与该foo类型关联的数据和行为的自定义代码。每个这样的foo类型插件在其模型和视图模块中都会有from generic-foo.models import *
或from generic-foo.views import *
这样的行。然后,我将在通用Foo
代码中包含以下代码。
import sys
import importlib
from django.db import models
from myproject import settings
class Foo(models.Model):
FOO_APPS = [(app_name, app_name) for app_name in
settings.INSTALLED_APPS if 'foo' in app_name]
app_name = models.CharField(max_length=256, choices=FOO_APPS)
# ... other model fields and generic business logic
def get_app(self):
"Return the app from which to get the right models or views for this object."
return importlib.import_module(self.app_name)
然后,使用gv
实例(或Foo
子类的实例)Foo
的任何通用视图obj
将首先调用app = obj.get_app()
,然后调用app.views.gv()
。基于类的视图可以处理其余的工作。 (请记住,常见的情况是视图是由子应用程序提供的。)由于星号导入,我可以从Foo
表中查找子ContentType
(或相关模型)运行查询ContentType.objects.get(app=obj.app_name, model=obj.__type__.__name__)
。
我这么做的很难吗? (另外,这里是否有安全漏洞,我没有看到?)
[1]我需要能够与客户共享代码而不泄露其他客户的代码。