在 django 模板 URL 标签中传递参数

Posted

技术标签:

【中文标题】在 django 模板 URL 标签中传递参数【英文标题】:pass parameter in django template URL tag 【发布时间】: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()方法将其替换为实际值。 【参考方案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 脚本的其余部分可以访问。也许它还没有被渲染……完全不确定……

以上是关于在 django 模板 URL 标签中传递参数的主要内容,如果未能解决你的问题,请参考以下文章

13.Django中几大常用模板标签讲解及实战使用 for循环;if判断;页面跳转;开启关闭自动转义;url携带参数传递;注释

Django:在 URL 模板标签中保留 GET 参数

Django:引用模板中的url名称并传递参数

Django - 自定义模板标签传递关键字参数

使用表单在 django 模板中传递 url 参数

无论如何在 Django 的模板 url 函数中传递超过 2 个参数?