django中的多态内联模型形式

时间:2011-04-25 21:08:44

标签: django-admin django-forms polymorphism

我有一个Person模型,它有许多动物模型作为宠物。狗是一种具有“最喜欢的骨骼”的动物,而猫是一种“喜欢猫薄荷?”的动物。田野和“最喜欢的鱼”场。

#models
class Person(db.model):
   pass

class Animal(db.model):
   models.ForeignKey(Person) #owner
   name = CharField()

class Dog(Animal):
   favorite_bone = CharField()

class Cat(Animal):
    favorite_fish = CharField()
    likes_catnip = BooleanField()

我想在人员管理表单中内联编辑所有人类宠物,但是,我已经读过Django内联管理表单不支持多态内联表单[1],其中,你只会得到父类字段(例如,不是favorite_bone或favorite_fish和likes_catnip字段。

这个问题来自哪里?

可以对框架进行哪些更改以适应这种情况?

如果不应该做出这些改变,为什么不呢?

[1] http://www.mail-archive.com/django-users@googlegroups.com/msg66410.html

3 个答案:

答案 0 :(得分:2)

(这是一个老问题,但我想我会添加一个答案,以防它仍然有用。我最近一直在研究类似的问题。)

我认为将Django表单生成更改为您想要的内容将具有挑战性。原因是内联formset对内联的所有行使用单个类/表单 - 没有内联表单的每行计算的配置选项。我通过阅读代码本身使自己确信这一点 - 在django.contrib.admin.options.py中查找“inline”和“formset”,尤其是第1039-1047行(版本1.5.1)。这也是您不能在现有项目中将某些字段设置为只读且在新项目中可更改的原因(例如,请参阅this SO question)。

为readonly案例找到的变通方法涉及一个自定义窗口小部件,它会产生所需的行为,例如this one。但是,这仍然不会直接支持多态性。我认为你需要最终将你的不同类型映射回一个共同的祖先(例如让所有宠物类能够返回其独特属性和值的字典),然后创建一个自定义小部件,渲染出多态部分您。然后,您必须在保存时重新映射值。

这可能比它的价值更具挑战性,并且可能会回到另一个答案的建议,即不使用管理员: - )

答案 1 :(得分:1)

可能看看here

但我认为modeladmin目前无法解决这些问题。 您可以为您的模型创建自定义编辑视图... 几乎所有事情都可能。

答案 2 :(得分:0)

可以使用Generic Relations执行此操作。