如何覆盖Django的ModelAdmin的"media"属性并使其动态化?

Tro*_*roy 6 javascript django django-admin django-modeladmin

最终,我想基于......包括/排除某些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",
        )
Run Code Online (Sandbox Code Playgroud)

这几乎可行,但我发现调用super(MyModelAdmin, self).media忽略了我当前类的媒体定义.在探索时,我发现这是因为父类的媒体属性被django.forms.widgets.media_property(via MediaDefiningClass)包裹,因为我正在覆盖媒体,我的媒体属性没有被包装.我尝试手动包装它:

from django.forms import media_property
MyModelAdmin.media = media_property(MyModelAdmin)
Run Code Online (Sandbox Code Playgroud)

但是media_property无法导入.

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

Tro*_*roy 11

在写完上述问题后不久,我发现了一种有效的技术.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
Run Code Online (Sandbox Code Playgroud)