Sorry… I’m not quite sure whether I can explain the problem clearly but allow me to give it a shot. English is my secondary language so please bear with me…
Here is some background information: I was trying to construct a small webpage for internal use, in which my colleagues can fill in the blank table and the data they inputted would be transferred to the backend using Django framework.
system: windows 10
django framework: 3.9.2
python: 3.9.6
Therefore, I constructed my view as the following:
# view.py
import ...
def post_form(request):
# check whether the request is ajax request and whether the method is post
if request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest' and request.method == 'POST':
form = evaluation_fee_form(request.POST)
if form.is_valid():
form.save()
test = request.POST
return JsonResponse({"instance": "saved successfully",
"form_isbound" : form.is_bound,
"django_backend": test}, status=200)
else:
return JsonResponse({"error": "error occurred"}, status=400)
return JsonResponse({"error": "Not AJAX request or Wrong request method"}, status=500)
the evaluation_fee_form was a modelForm subclass of the model evaluation_fee
# models.py
from django.db import models
class evaluation_fee(models.Model):
branch_name = models.CharField(max_length=5, blank=True)
sheet_no = models.CharField(max_length=10, blank=True)
fee = models.CharField(max_length=50, blank=True)
contract_no = models.TextField(null=True, blank=True)
client_id = models.TextField(null=True, blank=True)
notes = models.TextField(null=True, blank=True)
def __str__(self):
return self.branch_name
# forms.py
from django import forms
from .models import evaluation_fee
class evaluation_fee_form(forms.ModelForm):
class Meta:
model = evaluation_fee
fields = ("__all__")
widgets = {
'contract_no': forms.TextInput,
'client_id': forms.TextInput,
'notes': forms.TextInput,
}
and finally I had my html body as:
<html>
... some stylesheet...
<body>
... some other things...
<div class="table-responsive">
<form id="post_form">
{% csrf_token %}
<table class="table caption-top" id="post_table">
<caption style="font-size:36px">table title</caption>
<thead>
<tr>
{% for field in form %}
<th>{{ field.label }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
<tr>
{% for field in form %}
<td>
{{ field }}
</td>
{% endfor %}
</tr>
<tr>
{% for field in form %}
<td>
{{ field }}
</td>
{% endfor %}
</tr>
<tr>
{% for field in form %}
<td>
{{ field }}
</td>
{% endfor %}
</tr>
</tbody>
</table>
<input type="submit" class="btn btn-primary" value="submit">
</form>
</div>
</body>
... importing jQuery script...
<script type="text/javascript">
$(document).ready(function () {
$('#post_form').submit(function(i){
//first prevent the page from reloading and all other default actions
i.preventDefault();
var serializedData = $(this).serializeArray();
//make POST ajax call
$.ajax({
method:'POST',
url: "/post_form/ajax/form/",
data: serializedData,
success: function (response, django_backend, form_isbound) {
$("#post_form").trigger('reset');
console.log(serializedData);
console.log(response);
console.log(django_backend);
console.log(form_isbound);
alert("done!");
},
error: function (response) {
alert(response["responseJSON"]["error"]);
}
})
})
})
</script>
</html>
After I reviewed my code yesterday and I’m now having the assumption on the
...
<tr>
{% for field in form %}
<td>
{{ field }}
</td>
{% endfor %}
</tr>
...
of the html file: The intention of this bite of code was to build a table with 3 rows * 9 columns with 27 input “cells” like what we see in the MS excel but since I’m using the for loop, the <input>
fields in every rows were sharing the same "name"
attribute like:
<tr>
<td>
<input type="text" name="notes" class="table-responsive" id="id_notes">
</td>
</tr>
<tr>
<td>
<input type="text" name="notes" class="table-responsive" id="id_notes">
</td>
</tr>
In this way, the data transferred using request.POST retrieve only the last row of the input since the input with the same name overwrote the previous. Hence, the records in sqlite 3 database recored an empty record.
What I put in the table:
num |
contract |
1 |
W3324 |
2 |
W3314 |
3 |
S3304 |
sqlite 3 database:
Then, I manually changed the <name>
attributes as the following:
<tr>
<td>
<input type="text" name="notes" class="table-responsive" id="id_notes">
</td>
</tr>
<tr>
<td>
<input type="text" name="notes2" class="table-responsive" id="id_notes">
</td>
</tr>
This time, the data transferred using request.POST retrieve whatever I put but the sqlite 3 database recored only the input filed with name = what I’ve defined in the model:
What I put in the table:
num |
contract |
1 |
W3324 |
2 |
W3314 |
3 |
S3304 |
sqlite 3 database:
What I want is something like:
num |
contract |
1 |
W3324 |
2 |
|
|
|
3 |
S3304 |
(yes, the third row is left in blank on purpose)
sqlite 3 database:
num |
contract |
1 |
W3324 |
2 |
W3314 |
3 |
S3304 |
Any help is appreciated, thank you.