Как я могу переопределить свойство "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