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 %}

Back to Top