【问题标题】:Polymorphic inline model forms in djangodjango中的多态内联模型形式
【发布时间】:2026-01-18 17:15:01
【问题描述】:

我有一个 Person 模型,其中有许多 Animal 模型作为宠物。狗是具有“最喜欢的骨头”字段的动物,而猫是具有“喜欢猫薄荷”的动物?字段和“最喜欢的鱼”字段。

#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()

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

这个问题从何而来?

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

如果不应该进行这些更改,为什么不呢?

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

【问题讨论】:

  • +1: 好问题。你在 djangos 'bug'tracker 上发布了吗?

标签: django-admin django-forms polymorphism


【解决方案1】:

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

我相信改变 Django 表单生成来做你想做的事情是很有挑战性的。原因是内联表单集对内联的所有行使用单个类/表单——没有对内联表单的每行进行评估的配置选项。我通过阅读代码本身说服了自己——在 django.contrib.admin.options.py 中查找“inline”和“formset”,尤其是第 1039-1047 行(版本 1.5.1)。这也是您不能在现有项目中将某些字段设为只读而在新项目中可更改的原因(例如,请参阅this SO question)。

针对只读情况找到的解决方法涉及一个自定义小部件,该小部件会产生所需的行为,例如this one。然而,这仍然不会直接支持多态性。我认为您最终需要将您的不同类型映射回一个共同的祖先(例如,让所有宠物类能够返回其独特属性和值的字典),然后创建一个自定义小部件来呈现多态部分你。然后,您必须在保存时重新映射这些值。

这可能比它的价值更具挑战性,并且可能会导致另一个答案中的建议不要为此使用 admin :-)

【讨论】:

    【解决方案2】:

    可以看看here

    但我认为模型管理员目前无法执行此类操作。 您可以为您的模型创建自定义编辑视图... 几乎一切皆有可能。

    【讨论】:

      【解决方案3】:

      Generic Relations 或许可以做到这一点。

      【讨论】:

      • 泛型关系不适合这里。它们有助于通过内容类型关联模型。
      最近更新 更多