2010-04-27 50 views
48

我在Appengine上使用Django。我在任何地方都使用django reverse()函数,尽可能使所有内容保持干燥。Django中的干网址Javascript

但是,我无法将其应用于我的客户端JavaScript。有一个JS类根据传入的ID加载一些数据。有没有一种标准的方式来不硬编码这个数据应该来自的URL?

var rq = new Request.HTML({ 
    'update':this.element, 
}).get('/template/'+template_id+'/preview'); //The part that bothers me. 
+1

我很乐意看到的更多讨论这个。我也认为url解析回调太重了。有没有人在这个主题上找到其他的东西? – 2010-08-11 06:54:12

+0

类似的问题在这里:http://stackoverflow.com/questions/1795701/django-reverse-for-javascript – 2011-03-09 09:24:50

+0

奇怪我没有找到那个时候我张贴我的。虽然他们都没有令人满意的答案。 – noio 2011-03-22 12:57:50

回答

8

最合理的解决方案似乎是在JavaScript文件中传递URL列表,并在客户端上提供与reverse()等效的JavaScript。唯一的反对意见可能是整个URL结构暴露。

这是一个function(从这个question)。

4

好东西是假设从JavaScript的所有参数,Django会作为或request.GET中被request.POST传递。你可以在大多数情况下这样做,因为你不需要用于JavaScript查询的格式良好的URL。

然后唯一的问题是将url从Django传递到JavaScript。我已经为此发布了图书馆。示例代码:

urls.py

def javascript_settings(): 
    return { 
     'template_preview_url': reverse('template-preview'), 
    } 

的javascript

$.ajax({ 
    type: 'POST', 
    url: configuration['my_rendering_app']['template_preview_url'], 
    data: { template: 'foo.html' }, 
}); 
28

还有另一种方法,其不需要露出整个URL结构或AJAX请求用于解决各网址。虽然它不是真的很漂亮,它击败其他与简单:

var url = '{% url blog_view_post 999 %}'.replace (999, post_id); 

blog_view_post网址,不得含有神奇999数本身当然)。

+7

我一直这样做,感觉有点肮脏,但在这里看到它让我觉得更好一点。 – 2013-02-12 07:02:53

+0

请记住URL参数的预期字符类型。如果URL参数接受这个数字,但如果它只需要字母就不行。我也建议使用一些000,因为它不应该存在(对于一个object.id,至少) – jpimentel 2013-10-22 15:41:43

+1

这很脏。如果你打算在javascript中使用url,最好使它接受GET参数,然后你不需要替换。 GET已经成为了一个年龄标准,所有的javascript框架都支持传递一个数据结构,这个数据结构将被转换成参数(不像这样正确地转义),并且读得更好。 – dalore 2014-03-21 11:17:19

4

阿纳托利的答案相似,但更灵活一点。将在页面顶部:

<script type="text/javascript"> 
window.myviewURL = '{% url myview foobar %}'; 
</script> 

然后,你可以这样做

url = window.myviewURL.replace('foobar','my_id'); 

或什么的。如果您的网址包含多个变量,请多次运行replace方法。

1

我已经找到了这种简单的伎俩。如果您的网址就像是一个模式:

"xyz/(?P<stuff>.*)$" 

,并要在JS扭转,而无需实际提供的东西(推迟到JS运行时提供此) - 你可以做到以下几点:

阿尔特视图给该参数的默认值 - 没有的,并处理与错误响应,如果它不是设置:

意见。PY

def xzy(stuff=None): 
    if not stuff: 
    raise Http404 
    ... < rest of the view code> ... 
  • 改变URL匹配,使参数可选:"xyz/(?P<stuff>.*)?$"
  • 而且在模板的js代码:

    阿贾克斯({ 网址:“{{网址意见。 XYZ}}” + js_stuff, ...... })

生成的模板应该有JS中没有参数的URL,并且在JS中你可以简单地连接参数。

2

我喜欢Anatoly的想法,但我认为使用特定的整数是危险的。我通常希望指定一个对象ID,它总是需要积极的,所以我只是使用负整数作为占位符。这意味着将-?到URL定义,像这样:通过在JavaScript编写

{% url 'events.views.event_details' event_id=-1 %} 

并使用replace来替换占位符-1

url(r'^events/(?P<event_id>-?\d+)/$', events.views.event_details), 

然后我可以得到相反的URL在模板中,所以,在模板我会写类似

<script type="text/javascript"> 
var actual_event_id = 123; 
var url = "{% url 'events.views.event_details' event_id=-1 %}".replace('-1', actual_event_id); 
</script> 

这很容易地扩展到多个参数o,并且特定参数的映射直接在模板中可见。

+0

其实,我认为这样更加危险...... 1)现在URL中允许使用负号,这意味着它可以在你的视图中传递;你需要额外的逻辑来检查它2)“-1”更可能出现在URL中作为静态字符串的一部分而不是“999”。 “999”工作的原因是因为URL的静态部分中实际上并不包含“999”。无关紧要,只要它被替换为不含糊的内容即可。 – user193130 2014-03-24 16:15:17

+1

@ user193130如果它是一个对象ID,那么您应该可以使用'get_object_or_404' - 最终用户将会看到相同的404,就好像URL模式不接受负数 – Izkata 2014-07-15 23:48:40

0

我带来的解决方案之一是在后端生成url并以某种方式将它们传递给浏览器。

它可能不适合所有情况,但我有一个表(使用AJAX填充),并单击一行应使用户从该表中的单个条目。

(我正在使用django-restframeworkDatatables)。

从AJAX的每个条目都贴有网址:

class MyObjectSerializer(serializers.ModelSerializer): 
    url = SerializerMethodField() 
    # other elements 

    def get_url(self, obj): 
     return reverse("get_my_object", args=(obj.id,)) 

上装载AJAX每个URL连接的数据归因于行:

var table = $('#my-table').DataTable({ 
    createdRow: function (row, data, index) { 
     $(row).data("url", data["url"]) 
    } 
}); 

和点击我们使用的URL该数据属性:

table.on('click', 'tbody tr', function() { 
    window.location.href = $(this).data("url"); 
}); 
8

刚走挣扎,这一点,我想出了一个稍微不同的解决方案。在我的情况下,我想要一个外部的JS脚本来调用一个AJAX调用点击按钮(在做一些其他处理之后)。

在HTML,我用这样的HTML-5自定义属性

<button ... id="test-button" data-ajax-target="{% url 'named-url' %}"> 

然后,在JavaScript中,压根儿

$.post($("#test-button").attr("data-ajax-target"), ...); 

这就意味着Django的模板系统做了所有的reverse()逻辑我。

+0

+1这是我在搜索之前考虑的方法为其他人在做什么。似乎对我来说是理想的解决方案,除非遗留支持是一个问题。不知道为什么这里没有更多的牵引力。 – oogles 2016-08-27 22:55:11

+0

这真的很简单,你的例子正是我想要做的 – 5uperdan 2017-08-11 10:38:53

0

使用这个包:https://github.com/ierror/django-js-reverse

你必须在你的JS对象与Django中定义的所有URL。这是迄今为止我发现的最好的方法。

你需要做的就是添加生成的JS在你的基地模板的头部和运行管理命令来更新所产生的JS每次你添加一个网址唯一