制作包含多个键值的django html模板请求

时间:2016-11-27 03:29:31

标签: javascript html django-templates django-views django-urls

我刚开始使用Django甚至创建一个网站,所以如果我提供的关于我面临的问题的细节太少/太多,请耐心等待。此外,我花了上周的大部分时间来拖拽SO页面,博客,Django教程,Django文档等,试图自己解决这个问题。也许我忽略了一些事情,或者我只是运气不好,但我发现的任何内容都没有完全解决我的特殊情况。大多数示例似乎都专注于处理views.py中的请求,而不是如何在Django模板中处理原始请求。

我有一个Django模板 view_table.html ,它向用户显示一个Bootstrap DataTable表对象。此表的第二列是名为 MyRow_ID 的BigIntegerField。我目前在 MyCode.js 中有代码,允许用户突出显示多行,当点击按钮 modify_button 时, MyRow_ID 值为选定的行(例如[2,13,14])被捕获到名为 sent_data 的JS词典中。捕获这些值后,我希望 modify_button 创建一个发送 sent_data 的GET请求。在 urls.py 中进行匹配并在 views.py 中调用 modify_data 功能后, modify_data 应呈现新页面 modify_table.html ,同时传回与 MyRow_ID 匹配的模型实例,以便仅显示所选行的数据。我认为我非常接近,也许我只需要对正则表达式进行调整,但这是我的问题:

  1. 如何在Django模板 view_table.html 中创建GET请求,将 sent_data 传递给Django?目前我正在使用方法操作属性设置为“GET”“{%url'modit_data' sent_data = sent_data%}“。我假设GET并且不应该使用POST,因为请求没有修改后端,它更像是一个“过滤视图”类型的请求。这是正确的假设吗?请求的网址会是什么样的?说 MyRow_ID 值是[2,13,14]。获取请求看起来像 / modify_data / matched_row_1 = 2&amp; matched_row_2 = 13&amp; matched_row_3 = 14 ?我是否必须自己在模板中创建此url字符串,方法是迭代 sent_data 并附加“matched_row_n =”字符串,或者模板是否有更简单的方法在请求中自动创建?< / LI>
  2. myapp / urls.py 中应该使用的正确的正则表达式模式是什么,给定 sent_data 可以包含从1到n的唯一 MyRow_ID 值,假设分别选择1到n行? (显然,强大的代码将包括处理选择0行并单击 modify_button 的处理,但是现在让我们将它放在一边。)目前我在/ myapp / view_data /:使用参数'()'和关键字参数'{u'sent_data':''}'找不到'modify_data'。我是新手使用正则表达式,我知道我在 myapp / urls.py 错了。
  3. myapp / views.py 中的代码是否正确过滤匹配的模型实例并使用所选行呈现 modify_table.html
  4. view_table.html

    <!DOCTYPE html>
    <html>
      <head>
        ## Bunch of code… ##
      </head>
      <body>
        <div class="col col-xs-12 text-right">
          <form style="display" method="get" action="{% url 'modify_data' sent_data=sent_data %}">
            <button id="modify_button" type="button" class="btn btn-primary btn-create">Modify Data</button>
          </form>
        </div>
        <br><br><br>
        <table id="my_table">
          ## Code that displays my_table ##
        </table>
        <!-- Execute JS scripts -->
        <script type="text/javascript" src="{% static "myapp/js/jquery-1.12.0.min.js" %}"></script>
        <script type="text/javascript" src="{% static "myapp/js/jquery.dataTables.min.js" %}"></script>
        <script type="text/javascript" src="{% static "myapp/js/bootstrap.min.js" %}"></script>
        <script type="text/javascript" src="{% static "myapp/js/dataTables.bootstrap.min.js" %}"></script>
        <script type="text/javascript">
          var sent_data = [];
        </script>
        <script type="text/javascript" src="{% static "myapp/js/MyCode.js" %}"></script>
      </body>
    </html>
    

    MyCode.js

    $(document).ready(function(){
      var oTable = $('#my_table').DataTable();
      var selected_data = [];
    
      $('#my_table tbody').on('click','tr',function(){
        $(this).toggleClass('active');
      });
    
      $('#modify_button').click(function(event){
        selected_data = $.map(oTable.rows('.active').data(), function (item) {
          return item[1]
        });
        sent_data = { 'modify_rows': selected_data };
      });
    });
    

    我应该注意,我使用的是 MyRow_ID ,而不是原生的DataTable属性 rowID ,因为我假设DataTable是自动创建的 rowID 与Django正在使用的自动创建的主键( pk )不匹配。这是正确的假设吗?

    的myapp / urls.py

    from django.conf.urls import url
    from . import views
    from .models import MyDataModel
    
    urlpatterns = [
                    url(r'^view_data/$', views.view_data, name='view_data'),
                    url(r'^modify_data/(?P<sent_data>\d+)/$', views.modify_data, name='modify_data'),
                  ]
    

    的myapp / views.py

    from django.forms import modelformset_factory
    from django.shortcuts import render
    from django.http import HttpResponse
    from .models import MyDataModel
    
    def view_data(request):
      myData = MyDataModel.objects.all()
      return render(request, 'myapp/view_table.html', {'myData': myData})
    
    def modify_data(request, sent_data):
      MyDataFormSet = modelformset_factory(MyDataModel, fields=('MyRow_ID','MyRow_Text'))
      if request.method == 'GET':
        selected_rows = sent_data['modify_rows']
        ## selected_rows = request.GET['modify_rows']
        formset = MyDataFormSet(queryset=MyDataModel.objects.filter(MyRow_ID__in=selected_rows))
        selected_data = MyDataModel.objects.filter(MyRow_ID__in=selected_rows)
        return render(request, 'myapp/modify_data.html', {'formset': formset, 'selected_data': selected_data})
      else:
        return HttpResponse('A GET request was not received.')
    

    最后, modify_data.html

    <!DOCTYPE html>
    <html>
      <head>
        ## Bunch of code… ##
      </head>
      <body>
        <div class="col col-xs-12 text-right">
          <form method="post" action="">
            {% csrf_token %}
            {{ formset }}
            <button id="submit_changes" type="button" class="btn btn-primary btn-create">Submit Changes</button>
          </form>
        </div>
        <br><br><br>
        <table id="selected_rows_table">
          ## Code that displays selected rows passed as selected_data ##
        </table>
      </body>
    </html>
    

    非常感谢任何帮助,提前谢谢!

1 个答案:

答案 0 :(得分:0)

通过大量的试验和错误以及良好的老式谷歌搜索,我能够解决上述问题并更好地理解查询字符串,正则表达式模式甚至如何使用AJAX请求来实现我的原始目标。

我最初的目标是允许用户选择多行数据,单击按钮,然后在表单中同时编辑它们,所述表单要么在新页面上呈现,要么在模式中呈现。以下帖子/博客对每个难题都非常有帮助:

关于网址,请求/响应和模型表单集的Django文档:

https://docs.djangoproject.com/en/1.10/topics/http/urls/

https://docs.djangoproject.com/en/1.10/ref/request-response/

https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#model-formsets

创建Bootstrap模式的指南:

https://coolestguidesontheplanet.com/bootstrap/modal.php

了解网址和查询字符串如何使用单个键的多个值:

http://meyerweb.com/eric/tools/dencoder/(用于测试)

How to pass multiple values for a single URL parameter?

Capturing url parameters in request.GET

使用Django AJAX表单的示例:

http://schinckel.net/2013/06/13/django-ajax-forms/

处理来自服务器的AJAX请求响应并刷新页面的代码:

Update div with jQuery ajax response html

关于使用具有单个键的多个值的查询字符串的一个重要注意事项,例如说我的GET请求的网址类似于 www.myurl.com/?page=1&page=2&page=3 ;当使用AJAX GET请求时,它将为 www.myurl.com/?page [] = 1&amp; page [] = 2&amp; page [] = 3 创建此网址的查询字符串,即它添加了&#34; []&#34;具有多个值的任何键的括号。通常的答案(由Django和其他人记录)来检索&#34;页面的所有值&#34;在处理请求时,views.py中的键是使用 request.GET.getlist(&#39; page&#39;)。这不行。您需要使用 request.GET.getlist(&#39; page []&#39;)。在request.method.getlist()中添加括号,或从请求的url中的原始查询字符串中删除它们。

最后,这里有一些修改过的代码片段解决了我原来的问题:

view_data.html 中,更新后的表单:

<form id="modify_form" method="post" action="{% url 'modify_data' %}">
  {% csrf_token %}
  {{ formset }}
</form>

myapp / urls.py 中,修复了网址查找器以处理传递的任何查询字符串:

url(r'^modify_data/$', views.modify_data, name='modify_data'),

myapp / views.py 中,更改 modify_data 代码:

def modify_data(request):
  MyDataFormSet = modelformset_factory(MyDataModel, fields=('MyRow_ID','MyRow_Text'))
  if request.is_ajax():
    template = 'myapp/view_data.html'
  else:
    template = 'myapp/modify_data.html'

  if request.method == 'GET':
    selected_rows = request.GET.getlist['modify_rows[]']
    formset = MyDataFormSet(queryset=MyDataModel.objects.filter(MyRow_ID__in=selected_rows))
    selected_data = MyDataModel.objects.filter(MyRow_ID__in=selected_rows)
    return render(request, template, {'formset': formset, 'selected_data': selected_data})
  else:
    return HttpResponse('A GET request was not received.')

MyCode.js 中,代码已更新,以反映使用模态表单,AJAX GET请求并使用Django view.py的响应刷新DOM:

$("#modify_button").click(function(){
  selected_data = $.map(oTable.rows('.active').data(), function (item) {
   return item[1]
  });

  $.ajax({
    // The URL for the request
    url: URL,

    // The data to send (will be converted to a query string)
    data: {
      modify_rows: selected_data,
    },

    // Whether this is a POST or GET request
    type: "GET",
  })
    // Code to run if the request succeeds (is done);
    // The response is passed to the function
    .done(function( json ) {
      var forms_result = $('<div />').append(json).find('#modify_form').html();
      $('#modify_form').html(forms_result);
      var table_result = $('<div />').append(json).find('#my_table').html();
      $('#my_table').html(table_result);
    })
    // Code to run if the request fails; the raw request
    // and status codes are passed to the function
    .fail(function( xhr, status, errorThrown ) {
      alert( "Sorry, there was a problem!" );
      console.log( "Error: " + errorThrown );
      console.log( "Status: " + status );
      console.dir( xhr );
    })
});

希望所有这些对其他人有所帮助,如果没有,整个过程对我来说是一次很棒的学习经历!