Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I override the "media" property of Django's ModelAdmin and make it dynamic?

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?

like image 981
Troy Avatar asked Apr 25 '14 20:04

Troy


People also ask

What is the purpose of the admin site in a Django project?

The Django admin application can use your models to automatically build a site area that you can use to create, view, update, and delete records. This can save you a lot of time during development, making it very easy to test your models and get a feel for whether you have the right data.

How do I change the administrator name in Django?

To change the admin site header text, login page, and the HTML title tag of our bookstore's instead, add the following code in urls.py . The site_header changes the Django administration text which appears on the login page and the admin site. The site_title changes the text added to the <title> of every admin page.

What is Django admin interface?

One of the most powerful parts of Django is the automatic admin interface. It reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site. The admin's recommended use is limited to an organization's internal management tool.


1 Answers

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
like image 133
Troy Avatar answered Sep 27 '22 22:09

Troy