سؤال

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

نصائح أخرى

This works on Django 3.0:

@property
def media(self):
    response = super().media
    response._js_lists.append(["/js/en/leaflet.bundle.js"]))
    return response
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top