Как предоставить $сторонним внешним плагинам jQuery в администраторе Django

Я включил пару плагинов jQuery сторонних разработчиков в моем базовом шаблоне admin в Django, которые предполагают, что "$" будет доступен.

Для моего собственного кода я всегда был счастлив просто сделать

(function($) {
    my_code = 'here';
})(django.jQuery);

но как я могу предоставить "$" для кода других людей, который находится во внешних файлах?

<script src="{{ STATIC_URL }}js/jquery.json-2.2.min.js" type="text/javascript"></script>

жалуется, что "$" - undefined. Я попытался поставить

<script type="text/javascript">var $ = django.jQuery;</script>

перед этой внешней ссылкой, но безрезультатно (кстати, почему?) Я понимаю, что загрузка происходит одновременно, но выполнение? Я могу использовать этот "$" сразу после его определения.).

Я доволен версией jQuery, которую предоставляет Django admin и действительно не хочет загружать другую. Я также не хочу редактировать какой-либо плагин, чтобы он начинался с переопределения "$" выше. EDIT: я также не хочу обертывать его, как свой собственный код, я просто не хочу касаться этих файлов вообще.

Нужно ли мне прибегать к установке $.getScript() - http://api.jquery.com/jQuery.getScript - в мою анонимную функцию для загрузки таких файлов?

EDIT: после того, как я просмотрел внешний файл jquery.json-2.2.min.js, я увидел, что он уже был включен в функцию, которая предполагала, что "jQuery" будет доступен, а не "$" . После вставки

вар jQuery = django.jQuery;

перед внешней ссылкой он работал нормально. Но действительно ли это должно быть сделано?

Ответ 1

Переопределить статический файл django admin/js/jquery.init.js, создав файл с тем же именем и свой путь в каталоге приложений staticfile.

Исходным содержанием является

/* 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)
};

Просто удалите .noConflict(true).

Ответ 2

Да, я помню эту проблему. Я чувствую твою боль.

Отличным обходным решением является реструктуризация ваших js файлов таким образом, что Django может читать их как URL-адреса. В файле URL-адресов добавьте шаблон ниже:

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

Теперь, в init.py, добавьте следующий код:

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");

Как только код будет на месте и предположим, что у вас есть файлы javascript в /js/ *, вы можете включить свой javascript, используя следующий код:

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

Ответ 3

Для сторонних плагинов обычно лучше всего загружать собственную копию jQuery, прежде чем включать другие плагины. Для Django 1.4+ это может выглядеть так в вашем соответствующем файле admin.py:

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

Если ваши плагины не зависят от последней версии jQuery, вы также можете использовать включенную версию Django, указав $и jQuery в верхней части вашего плагина:

var jQuery = django.jQuery, $ = jQuery;

Начиная с версии 1.6, Django будет поставляться с jQuery 1.9.1. До этого используется jQuery 1.4, который не работает для большого количества новых/обновленных плагинов.