在Django Javascript中使用干url

我在Appengine上使用Django。 我在任何地方都使用django reverse()函数,尽可能保持一切为干。

但是,我有麻烦应用到我的客户端JavaScript。 有一个JS类,根据传入的ID加载一些数据。 有没有一个标准的方式来不硬编码这个数据应该从哪里来的URL?

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

还有另一种方法,它不需要公开整个url结构或parsing每个url的ajax请求。 虽然它不是很漂亮,但它简单易用:

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

blog_view_posturl本身不能包含魔力999号码。)

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

这是一个这样的function (从这个问题 )。

刚刚挣扎着,我想出了一个稍微不同的解决scheme。

在我的情况下,我想要一个外部JS脚本来调用一个button点击(在做一些其他处理之后)的AJAX调用。

在HTML中,我使用了HTML-5自定义属性

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

然后,在JavaScript中,只是做了

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

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

好的是假设从JavaScript到Django的所有参数都将作为request.GET或request.POST传递。 在大多数情况下,你可以做到这一点,因为你不需要格式化的JavaScript查询格式。

那么唯一的问题是将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' }, }); 

类似阿纳托利的回答,但更灵活一点。 放在页面的顶部:

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

那么你可以做一些类似的事情

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

pipe他呢。 如果你的url包含多个variables,只需多次运行replace方法。

我喜欢阿纳托利的想法,但我认为使用特定的整数是危险的。 我通常要指定一个对象ID,这总是要求积极,所以我只是使用负整数作为占位符。 这意味着添加-? 到url的定义如下所示:

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

然后,我可以通过写入来获取模板中的反向URL

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

并在JavaScript中使用replace来代替占位符-1 ,以便在模板中我会写类似的东西

 <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> 

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

我find了一个简单的技巧。 如果你的url是这样的模式:

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

而你想在JS中反转而不提供实际的东西(推迟到JS运行时间来提供这个) – 你可以执行以下操作:

改变视图给参数一个默认值 – 没有,并通过响应一个错误,如果没有设置:

views.py

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

    .ajax({url:“{{url views.xyz}}”+ js_stuff,…}}

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

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

它可能不适合在任何情况下,但我有一个表(填充AJAX),点击一行应该把用户从这个表中的单一条目。

(我正在使用django-restframework和Datatables )。

每个来自AJAX的条目都附有url:

 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"); } );