问题
假设我有三个类A,B和C,其中B是A的子类,C是B的子类:
A <- B <- C
当我打开管理员并列出所有“A”时,我看到所有“A”,“B”和“C”。但是,当我按照其中一个链接,查看详细信息并编辑特定B时,我将只看到B的字段,即使该实例实际上是C的实例。 我希望看到的是根据其最具体的类型向我展示的对象。
我正在尝试
我正在使用InheritanceManager来获取在更抽象级别工作时转换为正确类型的实例。这几乎很好用(它不能处理多个继承级别)。但是,即使对于单个继承级别,我也无法将多态行为反映在管理员中,因为显然管理员不知道管理器的select_subclasses()
方法。
我有什么想法可以用来在管理员身上获得类似多态的行为吗?
具体示例
models.py:
from django.db import models
from model_utils.managers import InheritanceManager
class A(models.Model):
a_field = models.CharField(max_length=200)
objects = InheritanceManager()
class B(A):
b_field = models.CharField(max_length=200)
class C(B):
c_field = models.CharField(max_length=200)
admin.py
from myapp.models import A, B, C
from django.contrib import admin
admin.site.register(A)
admin.site.register(B)
admin.site.register(C)
更新
添加一个来自2010年的两个主题的链接,并考虑如何使用django-polymorphic实现这一点:
答案 0 :(得分:2)
这个答案是不完整的,因为我无法重现您的第一个问题。当我列出父模型对象时,我会看到所有这些对象。 (或者可能存在一些误解。)
可以使用admin inline部分解决不完整字段的问题。由于子类只是具有隐式OneToOneField到父模型的模型,因此您可以为“C”定义内联,然后将其包含在B管理员的inlines
属性中。
问题是:
另一种方法是修改A的管理模板,在那里放置一个指向真实实例的链接(无论是B还是C)。但我想你已经想过了。
关于上一期:如果要修改某个模型管理员的查询集,可以通过ModelAdmin的queryset()
方法完成(参见this question中的示例)。您可以在模型的管理员上覆盖此方法,并在其中放置select_subclasses()
逻辑。但是我没有尝试过,所以如果你这样做,我不能说ModelAdmin的行为是什么。也许你需要覆盖更多的方法。
PS。我目前使用django-polymorphic
,从事具体继承的类似项目。它没有提供任何管理多态模型的方法,所以我决定不再依赖Django的管理员,只为站点人员创建一个简单的自定义界面,我想这不会花费太多时间。