【问题标题】:Django AJAX call/url from template after dropdown change下拉更改后模板中的 Django AJAX 调用/url
【发布时间】:2018-03-09 11:49:16
【问题描述】:

我如何正确地让 django 告诉我要将其发送到的 url,这样我就可以避免对其进行硬编码,以及如何在 JS 中执行它,一旦它被提供(我可以得到除了 @987654321 之外的所有内容的 url @ 之后再在 JS 中 concat ?)

网址/路由器

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

查看

def newRecipeAJAX(request, recipe_pk):
  if request.method == 'POST':
    return HttpResponseRedirect('/dashboard')
  # GET
  else:
    recipe_requested = get_object_or_404(Recipe, pk=recipe_pk)
    related_recipes = Recipe.related_recipes.all()      
    return {
      'recipe_requested': recipe_requested,
      'related_recipes': related_recipes,
    }

【问题讨论】:

  • 您的网址以? 结尾。你检查了吗?

标签: python ajax django


【解决方案1】:

更改您的模板中 url 格式的行,如下所示:

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作为占位符代替参数值,那就太好了,但据我所知,有没有。

【讨论】:

    【解决方案2】:

    我会在上下文中添加一个模板字符串,然后用它来替换 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 表单等)。这种职责混合可能是错误的一大来源。

    除此之外,这应该适用于您所拥有的以及您想要实现的目标。

    【讨论】:

      【解决方案3】:

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

      $(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 */
          });
      });
      

      【讨论】:

        猜你喜欢
        • 2016-05-11
        • 2019-02-05
        • 1970-01-01
        • 1970-01-01
        • 2012-01-16
        • 1970-01-01
        • 1970-01-01
        • 2020-12-25
        • 2011-01-07
        相关资源
        最近更新 更多