【问题标题】:Polymorphic behavior in django's Admindjango Admin 中的多态行为
【发布时间】:2011-08-13 05:28:23
【问题描述】:

问题

假设我有三个类 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 实现这一点的想法:

【问题讨论】:

    标签: django django-models django-admin


    【解决方案1】:

    这个答案是部分的,因为我无法重现您的第一个问题。当我列出父模型对象时,我会看到所有这些对象。 (或者可能有一些误解。)


    字段不完整的问题可以通过 admin inline 部分解决。由于子类只是一个对父模型隐含 OneToOneField 的模型,因此您可以为“C”定义一个内联,然后将其包含到 B 管理员的inlines 属性中。

    问题是:

    • 用户将无法通过 B 管理员中的内联创建“C”类对象;它只能通过 C 的管理员来完成。仅供查看。
    • 它不适用于多继承级别:您可以将 B 作为内联包含到 A 的管理员中,但我不知道将 C 作为内联包含到 B 的内联中的简单方法。

    另一种方法是修改 A 的管理模板,在其中放置一个指向真实实例(无论是 B 还是 C)的链接。不过我想你已经想到了。


    关于最后一个问题:如果你想修改一些模型管理员的查询集,可以通过 ModelAdmin 的queryset() 方法来完成(参见this question 中的示例)。您可以在模型的管理员上覆盖此方法,并将 select_subclasses() 逻辑放在那里。但是我还没有尝试过,所以我不能说如果你这样做,ModelAdmin 的行为会是什么。也许您需要覆盖更多的方法。


    PS。我目前使用django-polymorphic,从事具有具体继承的类似项目。它也没有提供任何通过 admin 管理多态模型的方法,所以我决定在这方面不太依赖 Django 的 admin,只为站点工作人员创建一个简单的自定义界面,我想这不会花费太多时间。

    【讨论】:

    • 我在问题中添加了一个具体示例。没错,列出所有“A”也会列出“B”和“C”。我也相应地解决了这个问题,并为剩下的问题添加了更多细节。
    • 感谢内联建议。我绝对可以使用它们解决一些问题,但正如你所说,它们的适用性非常有限,你提出的问题也不容忽视。 queryset() 方法效果很好,但它也仅适用于单个级别(不过,这更像是 InheritanceManager 的限制)。
    • 当然,忘记 django-admin 并从头开始做所有事情也是一种选择。我将“免费”管理员视为 django 的一大优势,但它开始对这个项目产生限制,因为它将广泛使用继承关系。
    • 我认为 Django 的 admin 很棒,但它的用例数量有限,文档没有说明这一点。乍一看,它非常棒,实际上就像您网站的“管理员”,但实际上它更像是一个数据浏览器(有其自身的局限性,如通用关系和复杂继承)。没关系,因为真正的“管理员”用例因站点而异。
    猜你喜欢
    • 2020-07-03
    • 2015-08-28
    • 1970-01-01
    • 2011-12-21
    • 2011-05-16
    • 1970-01-01
    • 2016-02-08
    • 2012-10-20
    • 2021-12-22
    相关资源
    最近更新 更多