【问题标题】:pass parameter in django template URL tag在 django 模板 URL 标签中传递参数
【发布时间】:2017-08-11 23:55:28
【问题描述】:

我正在尝试将参数传递给模板中的 django URL。网址配置为:

url(r'^reviewrecord/(?P<pk>\d+)/$', views.MyView, name='reviewrecord')

现在,我从 javascripyt 函数中的 ajax 块调用它。 javascript函数声明为:

function EditDialog(pk) {
    $.ajax(
      {
         url: "{% url 'reviewrecord' pk=pk %}",
         type: "POST",
         data: postData,
       });
}

这样做会导致:

Reverse for 'reviewrecord' with arguments '()' and keyword arguments '{u'pk': ''}' not found. 2 pattern(s) tried: ['reviewrecord/$', 'reviewrecord/(?P<pk>\\d+)/$']

但是,我已经验证,如果我硬编码 pk 值,它就可以工作。因此,将 url 参数替换为:

url: "{% url 'reviewrecord' pk=5 %}",

这行得通。所以,不知何故,我无法在 URL 标记的 JS 函数中引用传递的 pk 值。

根据下面的 cmets,我可以做到以下几点:

function EditDialog(pk) {
            $.ajax({
                url: "{% url 'populatereviewform' %}",
                method: 'GET',
                data: {
                pk: pk
            },
            success: function(formHtml){
                //place the populated form HTML in the modal body
                $('.modal-body').html(formHtml);
                $( "#dialog" ).modal({width: 500, height: 500});
            },
            dataType: 'html'
            });

这确实显示了正确填充所有内容的对话框。

我不确定如何在这种情况下实现类似的效果。我试过类似的东西:

var postData = $("#review-form").serializeArray();
$.ajax(
            {
                url: "{% url 'reviewrecord' pk %}",
                type: "POST",
                data: {
                  data: postData,
                  pk: pk,
            });

这更像是一次绝望的尝试,但没有奏效。

编辑

HTML模板如下:

{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}Cloud | Review data {% endblock %}

{% block content %}
    {% load static %}
    {% load render_table from django_tables2 %}

    <div id="dialog" class="modal" title="Edit" style="display:none">
        <div class="modal-dialog">
          <div class="modal-content">
              <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title">Review Uploaded Image</h4>
              </div>
              <div class="modal-body">
              </div>
          </div>
        </div>
    </div>

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>
    <link rel="stylesheet" type="text/css" href="{% static "project.css" %}" />

    <script>

        // using jQuery            
        function EditDialog(pk) {
            $.ajax({
                url: "{% url 'populatereviewform' %}",
                method: 'GET',
                data: {
                pk: pk
            },
            success: function(formHtml){
                //place the populated form HTML in the modal body
                $('.modal-body').html(formHtml);
                $( "#dialog" ).modal({width: 500, height: 500});
            },
            dataType: 'html'
            });

            $("#dialog").submit(function(e)
            {
                $.ajaxSetup({
                    beforeSend: function(xhr, settings) {
                        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                            xhr.setRequestHeader("X-CSRFToken", csrftoken);
                        }
                    }
                });

                var postData = $("#review-form").serializeArray();
                $.ajax(
                {
                    url: "{% url 'reviewrecord' pk=pk %}",
                    type: "POST",
                    data: postData,

                    success:function(data, textStatus, jqXHR)
                    {
                        //var transformed = data.replace('/-1/g', pk.toString())
                        $('.modal-body').html(data);
                    },
                    error: function(jqXHR, textStatus, errorThrown)
                    {
                        alert(errorThrown);
                    }
                });
                e.preventDefault();
                e.unbind(); //unbind. to stop multiple form submit.
            });
            return false;
            }
    </script>

    {% if reviews %}
     <div class="function-page">
         <div class="table-form">
                <div class="function-container">
                    {% render_table reviews %}
                </div>
         </div>
     </div>
    {% else %}
    <div class="form">
                        <div class="figcaption">Looks like you are all caught up! There is nothing to review.</div>
    </div>
    {% endif %}

{% endblock %}

【问题讨论】:

  • 好像pk没有传值。你确定它有价值吗?
  • 也试过了。结果:Reverse for 'reviewrecord' with arguments '('',)' and keyword arguments '{}' not found. 2 pattern(s) tried: ['reviewrecord/$', 'reviewrecord/(?P&lt;pk&gt;\\d+)/$']
  • 这有什么惊人的? Django 模板标签是在服务器端渲染的,远在 JS 可以运行之前。
  • 对...那么,在这种情况下传递此参数的方法是什么...
  • 我过去这样做的方法是在模板标签中放入一个不可能的值-例如00000-然后使用JS中的字符串.replace()方法将其替换为实际值。

标签: javascript ajax django django-templates


【解决方案1】:

对于像{% url 'reviewrecord' pk=pk %} 这样的模板标签,括号之间的任何内容,如pk 变量,都必须提前呈现。它不能从 javascript 传递。

现在,正如您在第二个示例中所示,您可以通过 GET 或 POST 请求传递数据:

function EditDialog(pk) {
        $.ajax({
            url: "{% url 'populatereviewform' %}",
            method: 'GET',
            data: {
            pk: pk
        },
...

这将获得一个类似/populatereviewform?pk=5 的网址,其中 pk=5。

如果你真的希望 django 从一个 javascript 调用中给你一个 url,你必须创建另一个视图。 Javascript:

function EditDialog(pk) { //pk=5
 $.get("{% url 'geturl' %}",{pk:pk}) // /geturl?pk=5
  .done(function(data){ // url returns data
    var the_url = data; // /reviewrecord/5
    $.ajax({
      url: the_url,
      type: "POST",
      data: postData,
  });
 });
}

urls.py:

url(r'^geturl/$', views.get_url_view, name='get_url'),

views.py:

from django.core.urlresolvers import reverse
from django.http import HttpResponse
...
def get_url_view(request):
  pk = request.GET['pk']
  the_url = reverse('reviewrecord', kwargs{'pk':pk})
  return HttpResponse(the_url)

虽然对于一个变量来说这似乎需要做很多工作,但您可以通过 GET 或 POST 数据传递。

【讨论】:

  • 感谢您的回复。问题是当我第一次打开对话框时,效果很好。第二次,主键没有更新为新值。本质上,$.get("{% url 'geturl' %}",{pk:pk}) // /geturl?pk=5 出于某种我还不知道的原因将主键保留为旧值。
  • 这听起来像是您的 Javascript 中某处的问题。除非我看到整个项目,否则我无法确定。 2 件事要测试: 1. http://yoursite.com/geturl/?pk=5 是否提供正确的网址? 2.看看能不能用不同的pk值调用EditDialog()函数。也许用&lt;a href="javascript:EditDialog(3)"&gt;创建一些按钮
  • 所有这些都奏效了。最后,我最终将 pk 值存储在 sessionStore 中,并且成功了。 ajax 部分不知何故永远无法访问较新的pk 值,尽管 JS 脚本的其余部分可以访问。也许它还没有被渲染……完全不确定……
猜你喜欢
  • 2021-06-05
  • 2021-02-15
  • 2014-08-06
  • 2011-01-08
  • 1970-01-01
  • 2021-02-11
  • 2011-08-18
  • 2019-07-31
  • 1970-01-01
相关资源
最近更新 更多