如何覆盖"媒体" Django的ModelAdmin的属性,并使其动态?

时间:2014-04-25 20:13:02

标签: 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",
        )

这几乎可行,但我发现调用super(MyModelAdmin, self).media会忽略我当前班级的媒体定义。在探索中,我发现这是因为父类的媒体属性由django.forms.widgets.media_property(通过MediaDefiningClass)包裹,因为我覆盖了媒体,我的媒体资产不是&# 39;被包裹我尝试通过以下方式手动包装它:

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

但media_property无法导入。

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

2 个答案:

答案 0 :(得分:11)

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

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

答案 1 :(得分:0)

这适用于Django 3.0:

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