Save multiple items in same form django
let say these are the inputs of user, in my view it's well validated form.is_valid().
item code | description | unit | quantity
---------------------------------------------------------------
#itemInput1 | #descriptionInput1 | #unitInput1 | #quantityInput1
#itemInput2 | #descriptionInput2 | #unitInput2 | #quantityInput2
#itemInput3 | #descriptionInput3 | #unitInput3 | #quantityInput3
reqeust.POST.getlist('description') return a list -> ['#descriptionInput1','#descriptionInput2','#descriptionInput3']
How can i save all the cells that the user enter to my MaterialIndent model??
just like in myview i could only save the last item only !!
# models
class MaterialIndent(models.Model):
material_indent_id = models.AutoField(primary_key=True)
date_request = models.DateTimeField(auto_now_add=True)
local_code = models.CharField(max_length=10, default='Local')
quotation = models.FileField(upload_to='files/', null=True, blank=True)
description = models.CharField(max_length=200)
unit = models.CharField(max_length=100)
quantity_requested = models.DecimalField(max_digits=12, decimal_places=2)
quantity_remained = models.DecimalField(max_digits=12, decimal_places=2, null=True)
request_for = models.CharField(max_length=50)
requester = models.ForeignKey(User, on_delete=models.CASCADE)
priority = models.CharField(max_length=100)
status = models.CharField(max_length=50, default='Store Checking')
def __str__(self):
return str(self.material_indent_id)
# form
class MaterialIndentForm(ModelForm):
class Meta:
model = MaterialIndent
fields = ['local_code', 'description', 'unit', 'quantity_requested', 'request_for', 'priority','quotation']
# views
def test(request):
available_stock = SparePartsStock.objects.filter(quantity__gte=0).values_list('local_code', flat=True)
if request.method == 'POST':
form = MaterialIndentForm(request.POST, request.FILES)
if form.is_valid():
length = len(request.POST.getlist('local_code'))
post = form.save(commit=False)
for r in range(length):
local_code = request.POST.getlist('local_code')[r]
description = request.POST.getlist('description')[r]
unit = request.POST.getlist('unit')[r]
quantity_requested = request.POST.getlist('quantity_requested')[r]
post.local_code = local_code
post.description = description
post.unit = unit
post.quantity_requested = quantity_requested
post.requester = request.user
post.quantity_remained = post.quantity_requested
post.status = 'Store Checking'
post.save()
print('form is valid')
else:
print(form.errors)
else:
sparestock = SparePartsStock.objects.all()
form = MaterialIndentForm()
context = {'form': form, 'stock':available_stock, 'table': sparestock}
return render(request, 'copy.html', {})
# template
{% extends 'inventory.html' %}
{% load static %}
{% load crispy_forms_filters %}
{% block title %}
SG
{% endblock %}
{% block head %}
<style>
.container{
padding: 100px;
}
#priority_label{
margin-left: 15px;
}
#submit_button {
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
background-color: #555555;/* Black */
}
.btn {
background-color: DodgerBlue;
border: none;
color: white;
padding: 12px 16px;
font-size: 16px;
cursor: pointer;
}
/* Darker background on mouse-over */
.btn:hover {
background-color: RoyalBlue;
}
#rowAdder{
margin-left: 15px;
right: 10px;
}
</style>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
<script src="{% static 'js/jQuery.js' %}"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"></script>
{% endblock %}
{% block content %}
<div class="container">
<h2 style="">Material Indent</h2>
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="card">
<div class="card-header">
<label id="priority_label" for="rate">Priority</label><br>
<div class="rate">
<input type="radio" id="star5" name="priority" value="High" required/>
<label for="star5" title="High">High</label>
<input type="radio" id="star4" name="priority" value="Medium" required/>
<label for="star4" title="Medium">Medium</label>
<input type="radio" id="star3" name="priority" value="Low" required/>
<label for="star3" title="Low">Low</label>
</div>
<input name="request_for" type="text" class="form-control m-input" placeholder="Requested For" required><br>
<label for="quotation">Quotation: </label>
<input type="file" name="quotation" placeholder="Quotation">
</div>
<div class="card-body">
<div class="">
<div class="col-lg-12">
<div id="row">
<div class="input-group m-3">
<div class="input-group-prepend">
<button class="btn btn-danger"
id="DeleteRow" type="button">
<i class="bi bi-trash"></i>
-
</button>
</div>
<input id="local_code0" name="local_code0" type="text" class="form-control m-input" placeholder="Local Code" required list="localList">
<datalist id="localList">
{% for item in stock %}
<option value={{ item }}>
{% endfor %}
</datalist>
<input name="description0" type="text" class="form-control m-input" placeholder="Description">
<input name="unit0" type="text" class="form-control m-input" placeholder="Unit">
<input name="quantity0" type="text" class="form-control m-input" placeholder="Quantity">
</div>
</div>
<div id="newinput"></div>
<button id="rowAdder" type="button"
class="btn btn-dark">
<span class="bi bi-plus-square-dotted" id="plus_sign">
</span> +
</button>
<input type="hidden" name="length" id="length">
</div>
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" class="button button5" id="submit_button">Submit</button>
</div>
</form>
</div>
<script type="text/javascript" >
let count = Number(1)
document.getElementById('length').value = 0
console.log(document.getElementById('length').value)
$("#rowAdder").click(function () {
document.getElementById('length').value = count
newRowAdd =
'<div id="row"> <div class="input-group m-3">' +
'<div class="input-group-prepend">' +
'<button class="btn btn-danger" id="DeleteRow" type="button">' +
'<i class="bi bi-trash"></i> - </button> </div>' +
'<input name=local_code' + count +' type="text" class="form-control m-input" placeholder="Local Code" list="localList" required>'+
'<input name=description'+count+ ' type="text" class="form-control m-input" placeholder="Description" required>'+
'<input name=unit'+count+ ' type="text" class="form-control m-input" placeholder="Unit" required>'+
'<input name=quantity'+count+ ' type="text" class="form-control m-input" placeholder="Quantity" required> </div> </div>'
;
$('#newinput').append(newRowAdd);
count ++
});
$("body").on("click", "#DeleteRow", function () {
$(this).parents("#row").remove();
count --
})
</script>
<script src="{% static 'js/material_indent_autofill.js' %}"></script>
{% include 'spare_parts_table.html' %}
{% endblock %}