【问题标题】:Django reverse() for JavaScript用于 JavaScript 的 Django reverse()
【发布时间】: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'),

【问题讨论】:

标签: javascript django url reverse


【解决方案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();
    });
    

    【讨论】:

    【解决方案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/
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-09-28
          • 2012-06-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-10
          • 2016-01-08
          相关资源
          最近更新 更多