Ultimately, I'd like to include/exclude certain javascript file(s) based on... whatever. Simply defining the Media class, by itself, won't work since that is only evaluated once.
I know I can do this by making a custom admin template, but I'm wondering if there's a simple way to do it by just making the media property dynamic.
This is what I have so far:
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",
)
And that almost works, but I found that calling super(MyModelAdmin, self).media
ignores my current class's Media definitions. In poking around, I found that this is because the parent class's media property is wrapped by django.forms.widgets.media_property
(via MediaDefiningClass
) and since I'm overriding media, my media property isn't being wrapped. I tried manually wrapping it via:
from django.forms import media_property
MyModelAdmin.media = media_property(MyModelAdmin)
but media_property fails to import.
How can I make it include my static media and my dynamic media, and how do I add my dynamic media in a way that django is happy with?
Shortly after writing up the above question, I found a technique that works. Instead of defining a Media
class, I just manually add ALL of my css/js via the media
method:
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