Search code examples
djangodjango-adminmediamodeladmin

Differentiate ModelAdmin media for add/change pages in Django


To encapsulate customized functionalities in Django admin I'm providing a custom ModelAdmin class that actually looks like this:

class ArticleAdmin(admin.ModelAdmin):
    class Media:
        js = ("my_code.js",)

I noted that my_code.js gets loaded both in add and change pages, but I need to load it only in the add page. Is it possible to do this (and how)?


Solution

  • Unfortunately the list of JavaScript files to include is generated and assigned by the media context variable provided from the admin application's view function, which you can't easily override. But here's one not-so-elegant solution:

    View source on the admin add page for your current model and copy the script tags that import the JavaScript files starting at line 14 (I'm using Django 1.2). You'll see where to paste them in the code fragment below.

    Create your own custom change_form.html template in your templates/admin/my_app/article directory, and place the following contents in the file:

    {% extends "admin/change_form.html" %}
    {% block extrahead %}
    {% url admin:jsi18n as jsi18nurl %}
    <script type="text/javascript" src="{{ jsi18nurl|default:"../../../jsi18n/" }}"></script>
    {% if add %}
    {{ media }}
    {% else %}
    <!-- originally generated script tags: may differ depending on your model's fields -->
    <script type="text/javascript" src="/media/admin/js/core.js"></script>
    <script type="text/javascript" src="/media/admin/js/admin/RelatedObjectLookups.js"></script>
    <script type="text/javascript" src="/media/admin/js/jquery.min.js"></script>
    <script type="text/javascript" src="/media/admin/js/jquery.init.js"></script>
    <script type="text/javascript" src="/media/admin/js/actions.min.js"></script>
    <!-- end originally generated script tags -->
    {% endif %}
    {% endblock %}
    

    Note that if you add a date field, for example, to your model, the field won't work properly on the change form when you edit a record, because a needed calendar.js file won't be called in. You'd have to add it manually if you made such a change.

    One alternative to go further with this and restore the lost dynamicness would be to create a template filter that you could pass the media variable into and use a regex, for example, to strip out the unwanted script tag.