Django 多态管理列表视图

Django polymorphic admin list views

我的 Django 代码中有一个全局配置变量列表,其中一些是整数,一些是字符串。

我目前正在使用 django-polymorphic,这样基础模型就有了名字,子模型就有了值。

例如:

class Configuration(PolymorphicModel):
    name = models.CharField(max_length=128, unique=True)

    def __str__(self):
        return self.name


class ConfigurationInt(Configuration):
    value = models.IntegerField(default=0)

    def __str__(self):
        return f'{self.name} = {self.value}'


class ConfigurationStr(Configuration):
    value = models.CharField(max_length=256,default='')

    def __str__(self):
        return f'{self.name} = {self.value}'

然后将模型注册到管理部分,如下所示:

@admin.register(Configuration)
class ConfigurationAdmin(PolymorphicParentModelAdmin):
    list_display = ('__str__',)
    child_models = (ConfigurationInt, ConfigurationStr)


@admin.register(ConfigurationInt)
class ConfigurationIntAdmin(PolymorphicChildModelAdmin):
    base_model = ConfigurationInt


@admin.register(ConfigurationStr)
class ConfigurationStrAdmin(PolymorphicChildModelAdmin):
    base_model = ConfigurationStr

不幸的是,__str__ 部分仅在“配置”的共享列表视图中显示基础 class 部分。 除了查看“ConfigurationInt”和“ConfigurationStr”的特定列表之外,我无法以任何方式访问该值。

有什么方法可以将它们实际列在一个漂亮的列表中吗?

让我们假设我忘记了 django-polymorphic 并使用稀疏数据,这样每个配置都有一个整数和一个字符串,以及一些说明它应该是什么的机制,比如整数类型。 然后我可以在 __str__ 实现中显示正确的数据,但是在编辑时,它会显示两者。 这在像这样的简单示例中可能没问题,但是我也有明显更复杂的模型,这些模型具有广泛的差异化领域,但在逻辑上都属于一个列表。 有没有办法在管理界面中 hide/show 某些字段,例如在 list_display 和 list_editable 中,基于字段?

长话短说,有什么方法可以在管理界面中正确实现多态列表吗? 让它在共享列表视图中可编辑会很棒,但即使只是实际显示信息,同时只能在对象本身内部或特定列表中编辑,也会很好。

埋在polymorphic.admin.parentadmin.py的源码里是这样的:

    #: Whether the list should be polymorphic too, leave to ``False`` to optimize
    polymorphic_list = False

    ...

    def get_queryset(self, request):
        # optimize the list display.
        qs = super(PolymorphicParentModelAdmin, self).get_queryset(request)
        if not self.polymorphic_list:
            qs = qs.non_polymorphic()
        return qs

哪种说得通。鉴于您可能在那里显示 20 个项目,因此在默认情况下尝试优化它是有意义的。该页面超时的可能性太大。

反正我觉得设置:

polymorphic_list = True

希望能为您解决这个问题:)

实际上,它也在文档中,(在实现细节下):

By default, the non_polymorphic() method will be called on the queryset, so only the Parent model will be provided to the list template. This is to avoid the performance hit of retrieving child models.

This can be controlled by setting the polymorphic_list property on the parent admin. Setting it to True will provide child models to the list template.