用于 JavaScript 的 Django reverse()
Posted
技术标签:
【中文标题】用于 JavaScript 的 Django reverse()【英文标题】:Django reverse() for JavaScript 【发布时间】:2010-12-20 05:21:23 【问题描述】:在我的项目中,我有很多 Ajax 方法,带有外部客户端脚本(我不想在模板中包含 javascript!),更改 URL 对我来说有点痛苦,因为我需要更改 URL在我的 Ajax 调用中手动。
有什么方法可以模拟 JavaScript 中 % url %
模板标签的行为吗?
例如,以 ^ajax
开头的打印 urlpatterns 和后面的脚本将模式替换为它们的实际值?
这就是我的想法,我的问题是 - 有没有常见的做法来做这样的事情?也许一些可重用的应用程序?此外,我很乐意阅读您的任何建议和相关想法。
更新 1: 我说的是计算 URL,而不是静态 URL:
url(r'^ajax/delete/(?P<type>image|audio)/(?P<item_id>\d+)/from/set/(?P<set_id>\d+)/$', 'blog.ajax.remove_item_from_set'),
【问题讨论】:
这能回答你的问题吗? Calling Django `reverse` in client-side Javascript 【参考方案1】:我通常将 URL 放入 <input type="hidden" />
元素或 rel=""
属性中。
然后,在编写 JS 时(使用下面的jQuery)我会这样做:
$('div#show_more').click(function ()
var url = $(this).attr('rel');
// or
var url = $('#more_url').val();
$.get(url, function () /* ... */ );
);
所有主流浏览器都很好地支持非标准属性,并且隐藏元素不必在表单中。
【讨论】:
你会如何处理计算的 url? url(r'^ajax/delete/(?P将 JavaScript 放入模板有什么问题?
您经常想在您的 html 模板中调用一个初始化函数,那么为什么不向它传递一个包含您将使用的 URL 的对象呢?
<script>
MYGLOBAL.mymodule.init(
fancy_ajax_url: '% url fancy %',
fancier_ajax_url: '% url fancier %'
);
</script>
如果您发现自己以这种方式传递了很多变量,或者想在 JavaScript 中使用 HTML 模板中的逻辑,那么为什么不通过 Django 的模板引擎渲染您的脚本呢?请记住,Django 模板不仅仅适用于 HTML 文档——通常它有助于将模板用于纯文本、XML、JSON,甚至是 JavaScript。担心性能?然后缓存结果。
【讨论】:
这是我任务的首字母,所以面对现实)JS文件将通过CDN传递。我能做的就是将 urlpatterns 放在我的页面顶部(设置 js 变量)并使用真实数据从正则表达式编译真实 url 这种方法的缺点是无法使用视图参数。 按照设计,混合语言是个坏主意。 这很容易受到 XSS 攻击 - 在 Django 模板中将变量传递给 JavaScript 的安全方法是 json_script 过滤器:docs.djangoproject.com/en/3.0/ref/templates/builtins/…【参考方案3】:https://github.com/mlouro/django-js-utils
dutils 是一个小型实用程序库,旨在为 JavaScript/Django 开发人员提供一些实用程序,这些实用程序将有助于在 Django 后端之上开发 RIA。
目前支持以下功能:
生成Django url的逆向方法...
【讨论】:
还可以查看一些分叉。 Dimitri-Gnidash 使用管理命令构建 URL。 ljosa 创建了一个动态构建它们的视图。 看来这个解决方案仍然需要硬编码 url_name:pattern 字典。自动生成在 dutils.conf.urls.example.js 中找到的列表会很好???【参考方案4】:我创建了一种机制,可以在您的 Django 项目中构建 url 模式列表并将其输出到 Javascript 文件中。它是 django-js-utils 的一个分支。
回购链接在这里: https://github.com/Dimitri-Gnidash/django-js-utils
【讨论】:
【参考方案5】:尝试创建用于生成 url 字符串的 javascript 帮助函数(在 django 模板中)。简单来说,它们可能如下所示:
function generete_some_url(id)
return "% url some_url itemid=112233 %".replace("112233", id);
也许这还有其他一些含义,但我认为它应该有效。
【讨论】:
你救了我的命,谢谢!只是一个观察,我想在占位符中使用 id=0 更好,因为你永远不会有一个等于 0,我们不能对 112233 说同样的话,但在另一个可以改变所有 0 的字符串,也许我们应该用一些模板来改变正确的位置。 很高兴您喜欢我的解决方案。关于 id 更重要的是,您要替换的值不在 url 字符串中的其他位置。所以它并没有真正计量它是 0 还是 112233,只要相同的值不在 url 字符串的其他地方。【参考方案6】:首先,您应该命名您的网址:
url(r'^blog/(?P<item_id>\d+)/$', 'blog.ajax.remove_item', name='blog-item'),
然后您可以将 url 作为变量传递给您的模块:
<script src=" STATIC_URL js/my-module.js"></script>
<script>
$(function()
MyModule.init('% url blog-item item.id %');
);
</script>
// js/my-module.js
var MyModule =
init: function(url)
console.log(url);
;
您可以在您的网址中使用令牌:
<script src=" STATIC_URL js/my-module.js"></script>
<script>
$(function()
MyModule.init("% url blog-item item_id='0000' %");
);
</script>
// js/my-module.js
var MyModule =
init: function(url)
var id = 1;
this._url = url;
console.log(this.url(id));
,
url: function(id)
return this._url.replace('0000', id);
;
请注意,您的令牌应该与正则表达式类型匹配才能成功解析(我不能使用item_id
作为令牌,因为它是用\d+
定义的)。
我对这个解决方案有点不满意,最后我编写了自己的应用程序来使用 django 处理 javascript:django.js。有了这个应用程序,我可以做到:
% load js %
% django_js %
% js "js/my-module.js" %
// js/my-module.js
var MyModule =
init: function()
var id = 1;
console.log(Django.url('blog-item', id));
;
$(function()
MyModule.init();
);
【讨论】:
使用% url %
或任何其他可能添加用户数据的标签容易受到 XSS 攻击 - 在模板中将数据传递给 JavaScript 的安全方法是 json_script
过滤器:docs.djangoproject.com/en/3.0/ref/templates/builtins/…
【参考方案7】:
为此,我们创建了一个名为 django-js-reverse 的小应用程序。
例如你可以检索一个命名的 url
urls.py:
url(r'^/betterliving/(?P[-\w]+)/(?P\d+)/$', 'get_house', name='betterliving_get_house'),
在 javascript 中像:
Urls.betterliving_get_house('house', 12)
结果:
/betterliving/house/12/
【讨论】:
【参考方案8】:您可以从 URL 中删除参数,并将动态部分作为查询参数传递:
$('#add-choice-button').on('click', function ()
var thing_id = $(this).closest('.thing').attr('data-item-id');
$.get('% url 'addThing' %?t='+thing_id, function (data)
...
);
);
【讨论】:
【参考方案9】:我发现了这个很酷的 django 应用,叫做 Django JS reverse
https://github.com/ierror/django-js-reverse
如果你有类似的网址
url(r'^/betterliving/(?P<category_slug>[-\w]+)/(?P<entry_pk>\d+)/$', 'get_house', name='betterliving_get_house'),
那你就做
Urls.betterliving_get_house('house', 12)
结果是
/betterliving/house/12/
【讨论】:
以上是关于用于 JavaScript 的 Django reverse()的主要内容,如果未能解决你的问题,请参考以下文章
用于 JavaScript 的 Django reverse()
用于 JavaScript 的 Django reverse()
Django框架中path及re_path中name参数的使用和模板渲染(八)