首页 \ 问答 \ 用多个键值创建一个django html模板请求(Making a django html template request with multiple key values)

用多个键值创建一个django html模板请求(Making a django html template request with multiple key values)

我对使用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创建一个GET请求,以便发送sent_data 。 在urls.py中匹配并调用views.py中modify_data函数后, modify_data应该呈现一个新页面modify_table.html,同时传回匹配MyRow_ID的模型实例以仅显示选定行的数据。 我认为我真的很接近,也许只是对正则表达式的调整是我需要的,但这里是我的问题:

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

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>

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


I'm new to using Django or even creating a website, so please bear with me if I have provided too little/much detail about the issue I'm facing. Also, I've spent the better part of the last week trolling SO pages, blogs, Django tutorials, Django documentation, etc. trying to solve the issue myself. Maybe I've overlooked something or I'm just unlucky, but nothing I've found addresses my particular situation in its entirety. Most examples seem to focus on handling requests in views.py and not on how the original request is made in the Django template.

I have a Django template, view_table.html, that displays a Bootstrap DataTable table object to a user. The second column of this table is a BigIntegerField called MyRow_ID. I currently have code in MyCode.js that allows the user to highlight multiple rows, and when button modify_button is clicked, the MyRow_ID values for the selected rows (e.g. [2, 13, 14]) are captured into a JS dict called sent_data. After these values have been captured, I'd like for modify_button to create a GET request that sends sent_data along with it. After matching in urls.py and calling the modify_data function in views.py, modify_data should render a new page modify_table.html while passing back the model instances matching MyRow_ID in order to display only the selected rows' data. I think I'm really close, and perhaps only a tweak to the regex expression is what I need, but here are my questions:

  1. How do I create a GET request in the Django template view_table.html that passes sent_data along to Django? Currently I'm using a form with the method and action attributes set to "GET" and "{% url 'modify_data' sent_data=sent_data %}" respectively. I'm assuming GET and not POST should be used because the request isn't modifying the backend, it's more of a "filter the view" type of request. Is this a correct assumption? What would the requested url look like? Say MyRow_ID values are [2,13,14]. Would the get request look something like /modify_data/matched_row_1=2&matched_row_2=13&matched_row_3=14? Do I have to create this url string myself in the template by iterating over sent_data and attaching a "matched_row_n=" string, or is there a simpler way for the template to create this automatically in the request?
  2. What's the correct regex pattern that should be used in myapp/urls.py, given sent_data could have anywhere from 1 to n unique MyRow_ID values, assuming 1 to n rows are selected respectively? (Obviously robust code would include handling where 0 rows are selected and modify_button is clicked, but let's set that aside for now.) Currently I'm getting a NoReverseMatch Error at /myapp/view_data/: Reverse for 'modify_data' with arguments '()' and keyword arguments '{u'sent_data': ''}' not found. I'm new to using regex, and I know what I have in myapp/urls.py is wrong.
  3. Is the code in myapp/views.py correct to filter the matching model instances and render modify_table.html with the selected rows?

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 };
  });
});

I should note that I'm using MyRow_ID and not the native DataTable attribute rowID because I'm assuming DataTable's automatically-created rowID do not match the automatically-created primary keys (pk) that Django is using. Is this a correct assumption?

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.')

Finally, 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>

Any help is much appreciated, thank you in advance!


原文:https://stackoverflow.com/questions/40825520
更新时间:2019-11-29 02:16

最满意答案

通过大量的试验和错误以及老式的Google搜索,我能够解决上述问题,并更好地理解查询字符串,正则表达式模式,以及如何使用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

了解URL和查询字符串如何针对单个键使用多个值:

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

如何为单个URL参数传递多个值?

在request.GET中捕获url参数

使用Django AJAX表单的例子:

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

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

用jQuery ajax响应html更新div

一个重要的事情要注意有关使用单个键的多个值的查询字符串,例如说我的GET请求的URL是类似www.myurl.com/?page=1&page=2&page=3 ; 当使用AJAX GET请求时,它将为www.myurl.com/?page[]=1&page[]=2&page[]=3创建该URL的查询字符串,即它为任何键添加“[]”括号具有多个值。 在处理请求时,通常的答案(如Django和其他人所记载的)在views.py中检索“page”键的所有值是使用request.GET.getlist('page') 。 这是行不通的。 你需要使用request.GET.getlist('page []') 。 在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查找器来处理传递的任何查询字符串:

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 );
    })
});

希望所有这些对其他人都有所帮助,如果不是的话,整个过程对我来说都是一次很好的学习体验!


Through much trial and error and good old-fashioned googling I was able to work out the above issues and gain a better understanding of query strings, regex patterns and even how to use an AJAX request to accomplish my original goal.

My original goal had been to allow the user to select multiple rows of data, click a button, and then edit them simultaneously in a form, said form either being rendered on a new page or in a modal. The following posts/blogs were very helpful for each piece of the puzzle:

Django documentation on urls, request/responses and model formsets:

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

Guide to creating Bootstrap modals:

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

Understanding of how urls and query strings work with multiple values for a single key:

http://meyerweb.com/eric/tools/dencoder/ (for testing)

How to pass multiple values for a single URL parameter?

Capturing url parameters in request.GET

Example of using Django AJAX Form:

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

Code for handling response from server of an AJAX request, and refreshing the page:

Update div with jQuery ajax response html

One important thing to note about using a query string with multiple values for a single key, e.g. say the url of my GET request is something like www.myurl.com/?page=1&page=2&page=3; when using an AJAX GET request, it will create a query string for this url with www.myurl.com/?page[]=1&page[]=2&page[]=3, i.e. it adds the "[]" brackets for any key with multiple values. The usual answers (as documented by Django and others) to retrieve all values of the "page" key in views.py when processing the request is to use request.GET.getlist('page'). THIS WILL NOT WORK. You need to use request.GET.getlist('page[]'). Add the brackets in request.method.getlist() or remove them from the original query string in the url requested.

Finally, here are some snippets of modified code that addressed my original questions:

In view_data.html, updated form:

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

In myapp/urls.py, fixed url finder to handle any query string passed:

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

In myapp/views.py, change modify_data code:

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.')

In MyCode.js, code has been updated to reflect using modal form, AJAX GET request and refreshing the DOM with Django view.py's response:

$("#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 );
    })
});

Hope all of this is somewhat helpful to someone else, if not, this whole process has been a great learning experience for me!

2017-05-23

相关文章

更多

最新问答

更多
  • jsPlumb draggable element javascript函数(jsPlumb draggable element javascript function)
  • MVC4:ViewModel(带有radiobuttonlist)在HttpPost之后为空(MVC4: ViewModel (with radiobuttonlist) is empty after HttpPost)
  • 如何在同一帐户上设置“Dev repo”(在prod和团队之间)(How to set up a “Dev repo” (between the prod and the team) on the same account)
  • 如何在tcl中将eth0配置为发送方udp端口(how to configure eth0 as a sender udp port in tcl)
  • 如何在datarow []中的列中找到最大值?(How to find max value in a column in a datarow[] ?)
  • 如何使用预定义文本替换来自数据库的部分结果(How do I replace part of result coming from Database with predefined text)
  • Selenium Java注入了新的Javascript函数(Selenium Java inject new Javascript function)
  • 使用.on的多个下拉菜单选择文本仅适用于第一个下拉列表(Multiple Dropdowns Menu Selection text using .on works only on first dropdown)
  • 快速将黄土曲线添加到大型数据集图中的方法(Quick way to add loess curve to large data set graph)
  • FilteringSelect in mvc(FilteringSelect in mvc)
  • 在Delphi XE2中开发Mac或iOS应用程序需要哪些硬件/软件?(What hardware/software is necessary to develop Mac or iOS apps in Delphi XE2?)
  • 在原型的构造函数中初始化属性时获取“未定义”(Getting 'undefined' when a property is initialized in the constructor of a prototype)
  • 通过越狱加载的应用程序的Documents文件夹位置(Location of Documents folder for an app loaded via jailbreak)
  • 在OpenGL中使用可编程和固定管道功能(Using both programmable and fixed pipeline functionality in OpenGL)
  • 将任何用户输入重定向到单独的底层程序(redirect any user input to a separate underlying program)
  • 编辑文本不能正常工作android(Edit texts not working properly android)
  • “user_denied”Facebook应用页面上的Facebook用户区域设置(Facebook user locale on “user_denied” facebook app page)
  • 在大图像中找到小的部分透明图像的坐标(find coordinates of small partially-transparent image within a large image)
  • 我如何在cakephp 3.1中获得完整的相对路径?(How i can get full relative path of image in cakephp 3.1?)
  • 如何保存拖动标记的新本地化?(How to save new localization of dragged marker?)
  • MySQL UPDATE vs INSERT和DELETE(MySQL UPDATE vs INSERT and DELETE)
  • 在执行查询之前,在SQLAlchemy模型中将datetime转换为unix时间戳?(Convert datetime to unix timestamp in SQLAlchemy model before executing query?)
  • OpenCL与OpenGL互操作的优势(Advantage of OpenCL interoperability with OpenGL)
  • 如何解析用点和等分隔的数据然后添加到listview(How to parsing data from delimited with dot and equal then add to listview)
  • 带调试输出的X3解析器段错误(BOOST_SPIRIT_X3_DEBUG)(X3 parser segfaults with debug output (BOOST_SPIRIT_X3_DEBUG))
  • 将文件夹名称添加到fgrep结果(Add folder name to fgrep result)
  • 在MySQL中加载一个表是非常慢的(Loading one table in MySQL is ridiculously slow)
  • 如何将JSON放入PHP变量?(How do I put JSON into a PHP Variable?)
  • 如何绕过Microsoft.Speech.Recognition中的不流畅?(How to bypass disfluencies in Microsoft.Speech.Recognition?)
  • 原点的最后一行是什么?(What is the last row of an origin for?)