下拉列表更改后,模板中的Django AJAX调用/ url

时间:2018-03-09 11:49:17

标签: python ajax django

我如何正确地让django告诉我发送它的url,所以我可以避免硬编码,如果它已经被提供,我如何在JS中做到这一点(我可以获得除{{{之外的所有内容的URL 1}}然后在JS中将它连接起来?)

URL /路由器

recipe_pk

在模板

url(r'^recipe/AJAX/(?P<recipe_pk>[a-zA-Z0-9]+)/?', views.newRecipeAJAX, name='newRecipeAJAX'),

视图

{% block script_inline %}
  $(function(){
    $('#form-dropdown').change(function () {
      var recipe_pk = $(this).val();
      {# This one doesn't know the recipe_pk yet, so it throws a NoReverseMatch error #}
      request_url = {% url 'recipes:newRecipeAJAX' recipe_pk=recipe_pk %};
      {# This one will too, since it doesn't have the argument #}
      request_url = {% url 'recipes:newRecipeAJAX' %};
      {# Tried to get a valid link, then JS remove it and add the correct pk, but it throws a JS console error of 'Uncaught SyntaxError: Invalid regular expression flags'#}
      request_url = "'' + {% url 'recipes:newRecipeAJAX' recipe_pk=1 %} + "'";
      alert(requst_url)
      // AJAX Land
    });
  });
{% endblock script_inline %}

3 个答案:

答案 0 :(得分:2)

更改格式化网址的模板行,如下所示:

var recipe_pk = $(this).val();
request_url = "{% url 'recipes:newRecipeAJAX' '999' %}".replace('999', recipe_pk);

说明:当django生成HTML时,url标记将在服务器端解释,形成以下javascript:

request_url = "/path/to/recipe/AJAX/999/".replace('999', recipe_pk);

如果您在浏览器中查看来源,您会看到此内容。

然后,在客户端,当您执行javascript时,它会将999替换为recipe_pk的值。

使用您喜欢的任何占位符而不是999 ..如果您需要替换带有字符串参数的参数,您可以使用更传统的东西,例如__ARG__。由于您的url正则表达式在这种情况下需要整数,因此占位符必须是整数。

这是我努力做到的最佳方式..在模板中只需要少量的额外代码,而在python中只需要一些。不幸的是Django最初并没有考虑到AJAX ......如果有一个特殊的反向函数返回包含参数名称的URL作为占位符代替参数值,那将是很好的,但据我所知,有无。

答案 1 :(得分:0)

我会在上下文中添加一个模板字符串,然后用它来替换url。

即。在我看来

from django.urls import reverse

def view_that_renders_javascript(request):
    reversed_path = reverse('recipes:newRecipeAJAX', kwargs={'recipe_pk':1})
    ajax_path = '/'.join(reversed_path.split('/')[:-2]) + '/'  # '/recipe/AJAX/`
    context = {
        'ajax_path': ajax_path
    }
    return render(request, 'your_template.html', context)

然后在模板内

{% block script_inline %}
  $(function(){
    var ajaxPath = '{{ajax_path}}';
    $('#form-dropdown').change(function () {
      var recipe_pk = $(this).val();
      request_url = ajaxPath + recipe_pk + '/';
      alert(request_url);
      // AJAX Land
    });
  });
{% endblock script_inline %}

总的来说,我觉得这是一个反模式django鼓励:通过模板注入运行时Javascript信息。我个人会让客户端通过API端点加载运行时配置,以便服务器负责提供信息,客户端负责运行时状态 - 但是当你执行页面时,这会更加麻烦在标准Django鼓励的每个动作之后加载(即Django形式等)。这种责任的混合可能是错误的重要来源。

有了这个警告,这应该适用于你拥有的和你想要实现的目标。

答案 2 :(得分:0)

我想这应该可以解决你的问题

$(function(){
    $('#form-dropdown').change(function () {
    var recipe_pk = $(this).val();
    request_url = "recipe/AJAX"+recipe_pk
    alert(requst_url);
    // AJAX Land
});

$(function(){
    $('#form-dropdown').change(function () {
    var recipe_pk = $(this).val();
    $.ajax({
        url: "recipe/AJAX"+recipe_pk,
        success: function(data){

        },/*./success*/
        error: function(xhr, status, error) {

        }/*  end of error */
    });
});