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:
- 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?
- 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.
- 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!