如何在 Django admin 中向第三方外部 jQuery 插件提供 $

Posted

技术标签:

【中文标题】如何在 Django admin 中向第三方外部 jQuery 插件提供 $【英文标题】:How to provide $ to third-party, external jQuery plugins in Django admin 【发布时间】:2011-07-25 23:13:18 【问题描述】:

我在我的 Django 管理基本模板中包含了几个第三方 jQuery 插件,它们假定“$”可用。

对于我自己的代码,我一直很乐意这样做

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

但是我怎样才能将“$”提供给位于外部文件中的其他人的代码?

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

抱怨“$”是未定义的。我试过把

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

在该外部引用之前,但无济于事(顺便说一句,这是为什么?我知道加载是同时发生的,但是执行?我可以在定义它后立即使用那个“$”。)。

我对 Django 管理员提供的 jQuery 版本很满意,并且真的不想加载另一个版本。我也不想编辑别人的插件,让它以上面的“$”重新定义开始。 编辑:我也不想像我自己的代码一样包装它,我根本不想碰这些文件。

我真的必须求助于将 $.getScript() - http://api.jquery.com/jQuery.getScript - 放入我的匿名函数来加载此类文件吗?

编辑:在实际查看外部文件 jquery.json-2.2.min.js 之后,我看到它已经被包装到一个假定“jQuery”可用而不是“$”的函数中。插入后

变量 jQuery = django.jQuery;

在外部参考之前,它工作正常。但这真的应该这样做吗?

【问题讨论】:

重新定义将是双重错误,因为您声明了一些对函数参数名称没有影响的全局变量。 对不起,这只是一个肮脏的解决方法的尝试。我已经编辑了这个问题,以澄清我根本不想接触那些外部库文件。 我的意思是肮脏的解决方法行不通。 :) 【参考方案1】:

通过在应用的 staticfiles 目录中创建一个具有相同名称和路径的文件来覆盖 django 的 staticfile admin/js/jquery.init.js

原文是这样的

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

【讨论】:

这带来的问题多于解决的问题。现在我所有的其他 jQuery 插件都在抱怨 jQuery 不存在。 我的场景是,我们有一堆现有的 JS 代码,它们依赖于 '$' 来使用 jQuery,并且我们正在使用一些 3rd 方小部件,其中包括 jquery.init.js。这破坏了我们的其他代码。这个解决方案效果很好。【参考方案2】:

对于第三方插件,通常最好在 之前加载您自己的 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,你也可以通过在插件顶部定义$和jQuery来使用Django包含的版本:

var jQuery = django.jQuery, $ = jQuery;

从 1.6 版开始,Django 将随 jQuery 1.9.1 一起发布。在此之前,使用的是 jQuery 1.4,它不适用于很多新的/更新的插件。

【讨论】:

【参考方案3】:

是的,我记得这个问题。我感觉到你的痛苦。

一个很好的解决方法是重组 js 文件,使 Django 可以将它们作为 URL 读取。在您的 URLs 文件中,添加以下模式:

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>

【讨论】:

1.就像我开始喜欢新的静态文件一样... 2. 还没有尝试过,有什么神奇的区别?这不只是动态地提供相同的静态文件吗?那个时候“$”出现了吗? 转念一想,没有。所有这些问题都是客户端的。 从顶部开始,从那里向下工作。首先,移动你的 $ = django.Jquery;分配高于一切,看看是否有效。如果没有,请确保您的所有 感谢您的帮助。请查看我的上一次编辑,我现在正在“工作”,只是想知道这是否是常见/推荐的做法。

以上是关于如何在 Django admin 中向第三方外部 jQuery 插件提供 $的主要内容,如果未能解决你的问题,请参考以下文章

django-admin.py 不是内部或外部命令

如何在 Django 中向 ManyToManyField 添加条目?

如何在 Django 中向 bootstrap4 添加松脆的表单?

如何在Django中向Python路径添加位置

如何在 Django 中向多对多关系中添加字段?

Django admin 根据另一个字段值过滤一个外部字段