Как я могу переопределить свойство "media" ModelAdmin в Django и сделать его динамическим?

В конечном счете, я хотел бы включить / исключить определенные файлы javascript, основанные на... что угодно. Простое определение класса Media само по себе не сработает, поскольку оно оценивается только один раз.

Я знаю, что могу сделать это, создав пользовательский шаблон администратора, но мне интересно, есть ли простой способ сделать это, просто сделав свойство 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 игнорирует определения Media моего текущего класса. В поисках я обнаружил, что это потому, что свойство media родительского класса обернуто django.forms.widgets.media_property (с помощью MediaDefiningClass) и так как я перезаписываю медиа, моя медиа-собственность не переносится. Я попытался вручную обернуть его через:

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

но media_property не удается импортировать.

Как я могу сделать так, чтобы он включал мои статические носители и мои динамические носители, и как мне добавить мои динамические носители так, чтобы django был доволен?

1 ответ

Решение

Вскоре после написания вышеупомянутого вопроса я нашел метод, который работает. Вместо определения 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

Это работает на Django 3.0:

@property
def media(self):
    response = super().media
    response._js_lists.append(["/js/en/leaflet.bundle.js"]))
    return response
Другие вопросы по тегам