如何覆盖 Django 的 ModelAdmin 的“媒体”属性并使其动态化?

Posted

技术标签:

【中文标题】如何覆盖 Django 的 ModelAdmin 的“媒体”属性并使其动态化?【英文标题】:How can I override the "media" property of Django's ModelAdmin and make it dynamic? 【发布时间】:2014-06-11 16:51:40 【问题描述】:

最终,我想根据...包含/排除某些 javascript 文件。简单地定义 Media 类本身是行不通的,因为它只评估一次。

我知道我可以通过制作自定义管理模板来做到这一点,但我想知道是否有一种简单的方法可以通过使媒体属性动态化来做到这一点。

这是我目前所拥有的:

from django.contrib import admin
class MyModelAdmin(admin.ModelAdmin):
    model = MyModel
    ...

    @property
    def media(self):
        media = super(MyModelAdmin, self).media
        if whatever_condition_I_want:
            # somehow add "my/js/file3.js"
        return media

    class Media:
        css = 
            "all": (
                "my/css/file1.css",
                "my/css/file2.css",
            )
        
        js = (
            "my/js/file1.js",
            "my/js/file2.js",
        )

这几乎可行,但我发现调用super(MyModelAdmin, self).media 会忽略我当前班级的媒体定义。在四处寻找时,我发现这是因为父类的媒体属性由django.forms.widgets.media_property(通过MediaDefiningClass)包装,并且由于我正在覆盖媒体,所以我的媒体属性没有被包装。我尝试通过以下方式手动包装它:

from django.forms import media_property
MyModelAdmin.media = media_property(MyModelAdmin)

但 media_property 无法导入。

如何让它包含我的静态媒体和我的动态媒体,以及如何以 django 满意的方式添加我的动态媒体?

【问题讨论】:

【参考方案1】:

写完上述问题后不久,我发现了一种有效的技术。我没有定义Media 类,而是通过media 方法手动添加我的所有css/js:

from django.contrib import admin
class MyModelAdmin(admin.ModelAdmin):
    model = MyModel
    ...

    @property
    def media(self):
        media = super(MyModelAdmin, self).media
        css = 
            "all": (
                "my/css/file1.css",
                "my/css/file2.css",
            )
        
        js = [
            "my/js/file1.js",
            "my/js/file2.js",
        ]
        if whatever_condition_I_want:
            js.append("my/js/file3.js")
        media.add_css(css)
        media.add_js(js)
        return media

【讨论】:

【参考方案2】:

这适用于 Django 3.0:

@property
def media(self):
    response = super().media
    response._js_lists.append(["/js/en/leaflet.bundle.js"]))
    return response

【讨论】:

以上是关于如何覆盖 Django 的 ModelAdmin 的“媒体”属性并使其动态化?的主要内容,如果未能解决你的问题,请参考以下文章

在 django 中测试 admin.ModelAdmin

如何在 django admin 中组合两个或多个 ModelAdmin

django 内联覆盖保存

如何在 ModelAdmin.formfield_for_manytomany() 中使用 Django QuerySet.union()?

如何在 Django ModelAdmin 中创建和保存动态字段?

添加 list_filter 时,如何在 django modeladmin 更改列表中修复/设置列宽?