用于 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 放入 &lt;input type="hidden" /&gt; 元素或 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/(?Pimage|audio)/(?P\d+)/from/set/(?P\d+)/$', 'blog. ajax.remove_item_from_set'), 你把它们放在页面上的某个地方(在 django 模板中)——javascript 是一个单独的文件,不是由 django 生成的。【参考方案2】:

将 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的一些问题

Django框架中path及re_path中name参数的使用和模板渲染(八)

django url reverse不适用于命名的url(重新编辑)找到了原因,但现在卡住了!

django通过javascript登录[重复]