在客户端Javascript中调用Django`reverse`
我在Appengine上使用Django。我在任何地方都使用django在客户端Javascript中调用Django`reverse`,javascript,ajax,django,google-app-engine,dry,Javascript,Ajax,Django,Google App Engine,Dry,我在Appengine上使用Django。我在任何地方都使用djangoreverse()函数,尽可能保持一切干燥 但是,我在将其应用于客户端javascript时遇到了问题。有一个JS类根据传入的ID加载一些数据。是否有一种标准方法不硬编码这些数据应该来自的URL var rq = new Request.HTML({ 'update':this.element, }).get('/template/'+template_id+'/preview'); //The part that
reverse()
函数,尽可能保持一切干燥
但是,我在将其应用于客户端javascript时遇到了问题。有一个JS类根据传入的ID加载一些数据。是否有一种标准方法不硬编码这些数据应该来自的URL
var rq = new Request.HTML({
'update':this.element,
}).get('/template/'+template_id+'/preview'); //The part that bothers me.
最合理的解决方案似乎是在JavaScript文件中传递URL列表,并在客户端提供与reverse()等效的JavaScript。唯一的反对意见可能是整个URL结构都被公开了
这里就是这样一个例子。好的事情是假设从JavaScript到Django的所有参数都将作为request.GET或request.POST传递。在大多数情况下都可以这样做,因为JavaScript查询不需要格式良好的URL 然后唯一的问题是将url从Django传递到JavaScript。我为此出版了图书馆。示例代码: url.py
def javascript_settings():
return {
'template_preview_url': reverse('template-preview'),
}
def xzy(stuff=None):
if not stuff:
raise Http404
... < rest of the view code> ...
javascript
$.ajax({
type: 'POST',
url: configuration['my_rendering_app']['template_preview_url'],
data: { template: 'foo.html' },
});
还有另一种方法,它不需要公开整个url结构或解析每个url的ajax请求。虽然它不是很漂亮,但它比其他的简单:
var url = '{% url blog_view_post 999 %}'.replace (999, post_id);
(
blog\u view\u post
URL当然不能包含神奇的999
数字本身。)与Anatoly的答案类似,但更灵活一些。将以下内容放在页面顶部:
<script type="text/javascript">
window.myviewURL = '{% url myview foobar %}';
</script>
或者别的什么。如果url包含多个变量,只需多次运行replace方法。我发现了一个简单的技巧。如果您的url是如下模式:
"xyz/(?P<stuff>.*)$"
“xyz/(?P.*)”
如果您希望在JS中进行反向操作,而不实际提供任何内容(请根据JS运行时提供),您可以执行以下操作:
更改视图,为参数指定默认值-无,如果未设置,则通过响应错误来处理该值:
视图.py
def javascript_settings():
return {
'template_preview_url': reverse('template-preview'),
}
def xzy(stuff=None):
if not stuff:
raise Http404
... < rest of the view code> ...
def xzy(stuff=None):
如果不是什么东西:
提高Http404
... < 视图代码的其余部分>。。。
- 更改URL匹配以使参数可选:
“xyz/(?P.*)?$”
- 在模板js代码中: .阿贾克斯({ url:“{url views.xyz}}”+js_stuff, ... ... })
生成的模板应该在JS中包含不带参数的URL,在JS中,您可以简单地在参数上串联。我喜欢Anatoly的想法,但我认为使用特定的整数是危险的。我通常希望指定一个值,比如说一个对象id,它总是要求为正,所以我只使用负整数作为占位符。这意味着向url定义中添加
-?
,如下所示:
url(r'^events/(?P<event_id>-?\d+)/$', events.views.event_details),
并在javascript中使用replace
替换占位符-1
,以便在模板中编写如下内容
url = window.myviewURL.replace('foobar','my_id');
<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>
var实际事件id=123;
var url=“{%url”events.views.event_details'event_id=-1%}”。替换('-1',实际_event_id);
这也很容易扩展到多个参数,并且特定参数的映射可以直接在模板中看到。我提供的解决方案之一是在后端生成URL,并以某种方式将它们传递给浏览器 它可能并不适用于所有情况,但我有一个表(用AJAX填充),单击一行应该可以让用户从该表中找到单个条目 (我正在使用和) 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");
} );
在与之斗争之后,我想出了一个稍微不同的解决方案 在我的例子中,我需要一个外部JS脚本来在点击按钮时调用AJAX调用(在完成一些其他处理之后) 在HTML中,我使用了一个HTML-5自定义属性
<button ... id="test-button" data-ajax-target="{% url 'named-url' %}">
这意味着Django的模板系统为我完成了所有的reverse()
您将在JS中拥有一个对象,其中包含django中定义的所有URL。这是迄今为止我发现的最好的方法
您需要做的唯一一件事是在基本模板的头部添加生成的js,并在每次添加url时运行管理命令更新生成的js,我在配置url时总是使用字符串而不是整数,即。
而不是像
... r'^something/(?P<first_integer_parameter>\d+)/something_else/(?P<second_integer_parameter>\d+)/' ...
然后,在javascript中,我可以将字符串作为占位符,django模板引擎也不会抱怨:
...
var url = `{% url 'myapiname:urlname' 'xxz' 'xxy' %}?first_kwarg=${first_kwarg_value}&second_kwarg=${second_kwarg_value}`.replace('xxz',first_integer_paramater_value).replace('xxy', second_integer_parameter_value);
var x = new L.GeoJSON.AJAX(url, {
style: function(feature){
...
url将保持不变,即something/911/something\u else/8/
。
这样可以避免整数参数替换问题,因为as参数中不需要字符串占位符(a、b、c、d、…z)我希望看到更多关于这方面的讨论。一、 同样,认为url解析回调太重。有人在这个主题上发现了其他的东西吗?这里有一个类似的问题:奇怪的是,我在发布我的主题时没有找到那个。虽然没有令人满意的答案,呵呵。我一直在这样做,感觉有点脏,但在这里看到它让我感觉稍微好一点。记住URL参数的预期字符类型。如果URL参数接受数字,则此操作有效,但如果它只需要字母,则不起作用。我还建议使用大约000,因为它不应该存在(至少对于object.id而言),这是肮脏的。如果要在javascript中使用url,最好让它接受GET参数,然后不需要替换。GET是多年来的标准,所有javascript框架都支持传递一个数据结构,该结构将被转换为参数(正确转义也与此不同),并且可读性更好。@jpimental如果将000
传递给Django,它将在URL中呈现为0
@dalore使用GET参数的一个问题是RESTURL,例如,/api/model/3/
是与/api/model/
不同的URL
...
var url = `{% url 'myapiname:urlname' 'xxz' 'xxy' %}?first_kwarg=${first_kwarg_value}&second_kwarg=${second_kwarg_value}`.replace('xxz',first_integer_paramater_value).replace('xxy', second_integer_parameter_value);
var x = new L.GeoJSON.AJAX(url, {
style: function(feature){
...