[Solved]-How to provide $ to third-party, external jQuery plugins in Django admin

6👍

Override django’s staticfile admin/js/jquery.init.js by creating a file with the same name and path in your app’s staticfiles directory.

The original content is this

/* Puts the included jQuery into our own namespace using noConflict and passing
 * it 'true'. This ensures that the included jQuery doesn't pollute the global
 * namespace (i.e. this preserves pre-existing values for both window.$ and
 * window.jQuery).
 */
var django = {
    "jQuery": jQuery.noConflict(true)
};

Just remove the .noConflict(true).

1👍

Yeah, I remember this problem. I feel your pain.

A great workaround is to restructure your js files in such a way that Django can read them as URLs. In your URLs file, add the pattern below:

urlpatterns = patterns((r"^js(?:/(?P<type>\w+))?", "app.views.render_js"))

Now, in your init.py, add the following code:

JS_FILES = {"name" : "name.js",
            "thing" : "thing.js"};

def render_main_js(req, type = None) :
    return render_to_response(JS_FILES.get(type, "main.js"), mimetype="text/javascript");

Once the code is in place and assuming you have your javascript files in /js/* you can include your javascript by using the code below:

<script type="text/javascript" src="/js/name"></script>
<script type="text/javascript" src="/js/thing"></script>

1👍

For third party plugins, it’s usually best to load your own copy of jQuery before including the other plugins. For Django 1.4+ this may look like so in your corresponding admin.py file:

class Media:
    js = (
        'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
        '/static/js/third_party_plugin.js',
    )

If your plugins do not depend on a recent version of jQuery, you may also use Django’s included version by defining $ and jQuery at the top of your plugin:

var jQuery = django.jQuery, $ = jQuery;

As of version 1.6, Django will ship with jQuery 1.9.1. Before that, jQuery 1.4 is used, which does not work for a lot of new/updated plugins.

1👍

There is a solution that works without double loading of jQuery, and without hacking jquery.init.js. It relies on the order the libraries are loaded in the admin.

Idea

  1. load jquery
  2. load third party libraries that depend on jQuery/$
  3. optional, load your own scripts, that use jQuery/$
  4. load jquery.init.js from Django (does the django.jQuery and noConflict thing)
  5. optional, load your own scripts, that use django.jQuery

Example

Media Attribute of an Admin, including select2.js.

    class Media:
        js = [
            'admin/js/vendor/jquery/jquery.js',
            'admin/js/vendor/select2/select2.full.js',
            'your_own/js/your_own-using-django.jQuery.js',            
            'admin/js/jquery.init.js',
            'your_own/js/your_own-using-django.jQuery.js',
        ]

Leave a comment