【问题标题】:How can I override the "media" property of Django's ModelAdmin and make it dynamic?如何覆盖 Django 的 ModelAdmin 的“媒体”属性并使其动态化?
【发布时间】: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 满意的方式添加我的动态媒体?

【问题讨论】:

    标签: javascript django django-admin django-modeladmin


    【解决方案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
      

      【讨论】:

        猜你喜欢
        • 2013-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-08
        • 1970-01-01
        • 2016-03-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多