在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_post
url本身不能包含魔力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"); } );