如何在Django管理主页中加载自定义JS文件?

22

我有一个高度定制的Django管理界面,对于每个ModelAdmin加载自定义JS文件非常简单:

class MyModelAdmin(admin.ModelAdmin):
    class Media:
        js = ('js/admin/mymodel.js',)

但是,我如何在管理员“主页”上执行此操作,以列出所有我的管理员模型?

更新#1:修改我的问题,因为如果我不能有效地包含Django的jQuery,则下面的解决方案并不那么有用。 那么,我该如何在JS文件中包含Django的jQuery? 如果我像在其他ModelAdmin JS文件中一样使用以下代码:

(function ($) {
    // my code here...
})(django.jQuery);

我遇到了以下错误:

ReferenceError: django未定义。

谢谢。 更新 #2: 我成功地按照这个答案https://dev59.com/G2kv5IYBdhLWcg3wdQlT#10584539包含了Django的jQuery。
2个回答

33

您可以覆盖 templates/admin/index.html 并将 JavaScript 添加到块 extrahead 中:

{% extends "admin/index.html" %}

{% block extrahead %}
    {{ block.super }}
    # add a <script> tag here with your JavaScript
{% endblock %}

这个代码看起来干净有效,谢谢。不过,我该如何在JS文件中引入jQuery呢?如果我像我的其他ModelAdmin JS文件一样用(function ($) { ... })(django.jQuery);来包装我的代码,我会得到一个“引用错误:django未定义”的错误提示。 - Cloud Artisans
6
以上解决方案将覆盖extrahead块中包含的所有代码,这可能是“ReferenceError: django未定义”错误的原因。如果在“{% block extrahead %}…{% endblock %}”现有代码内添加“{{ block.super }}”,则可以保留现有代码。 - tobltobs
1
@tobltobs,我更新了答案。现在看起来正确吗? - guettli
3
无法使用。将模板添加到 templates/admin/index.html 中没有改变任何内容。 - EugZol
1
@MikeSchem 那是很久以前的事了,我不记得接下来我做了什么。目前我看到 ./template/admin/<app_name>/base_site.html。该文件的第一行是 {% extends "admin/base_site.html" %}<app_name> 是项目中一个子文件夹的名称,在其中我放置了所有管理员模型。希望这可以帮到你。 - EugZol
显示剩余2条评论

3
你只能在“首页”管理页面上加载自定义的js文件。*我的回答解释了如何在Django中加载CSS和JavaScript文件。
例如,将BASE_DIR / 'templates'设置为DIRSTEMPLATES中,并将BASE_DIR / 'static/'设置为STATICFILES_DIRSsettings.py中,如下所示,这样Django就可以识别django-project下的templatesstatic文件夹。*我的答案解释了如何设置Django模板,我建议按照我的答案设置whitenoise以禁用浏览器缓存Django的静态文件:在settings.py中,如下所示:
# "core/settings.py"

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            BASE_DIR / 'templates' # Here
        ],
        ...
    },
]

...

STATIC_URL = 'static/'
STATICFILES_DIRS = [
    BASE_DIR / 'static/' # Here
]

然后,在static/admin/js/中创建custom.js,并将django/contrib/admin/static/admin/index.html中的index.html从您的虚拟环境复制到templates/admin/中,如下所示:
django-project
 |-core
 |  └-settings.py
 |-app1
 |-app2
 |-static
 |  └-admin
 |     └-js
 |        └-custom.js # Here
 └-templates
    └-admin
       └-index.html # Here

然后,将alert("Hello World");设置为custom.js,如下所示:
# "static/admin/js/custom.js"

alert("Hello World");

然后,在index.html中的{% block sidebar %}之后设置custom.js,如下所示:
# "templates/admin/index.html"

# ...
{% block sidebar %}
{# ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ Here ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ #}
<script src="{% static 'admin/js/custom.js' %}" defer></script>
{# ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ Here ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ #}
<div id="content-related">
# ...

现在,Hello World只显示在Home管理页面上,如下所示:

enter image description here

此外,您可以在所有管理员页面上加载custom.js

因此,请将位于虚拟环境中的django/contrib/admin/static/admin/base.htmlbase.html复制到templates/admin/,如下所示:

django-project
 |-core
 |  └-settings.py
 |-app1
 |-app2
 |-static
 |  └-admin
 |     └-js
 |        └-custom.js
 └-templates
    └-admin
       └-base.html # Here

然后,在`base.html`中在``之后设置`custom.js`,如下所示,然后在所有管理员页面上显示`Hello World`。
# "templates/admin/base.html"

# ...
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="{% block stylesheet %}{% static "admin/css/base.css" %}{% endblock %}">
{# ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ Here ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ #}
<script src="{% static 'admin/js/custom.js' %}" defer></script>
{# ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ Here ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ #}
{% block dark-mode-vars %}
  <link rel="stylesheet" href="{% static "admin/css/dark_mode.css" %}">
# ...

小心,django/contrib/admin/static/admin/js/ 包含 Django Admin 的 js 文件,因此您不应在其中使用相同的文件名添加自定义的 js 文件到 Django Admin,除非您需要覆盖它们。

运行下面的代码可以将 Django 项目中的所有静态文件收集到 static 文件夹中,而不会删除自定义和被覆盖的 js 文件。

python manage.py collectstatic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接