Formset
Create A Model
from django.db import models
# Create your models here.
class Item(models.Model):
item_code = models.CharField(max_length=20)
item_name = models.CharField(max_length=255)
item_description = models.TextField()
item_price = models.DecimalField(max_digits=10,decimal_places=2)
item_qty = models.PositiveIntegerField()
item_picture = models.ImageField(upload_to='items/')
def __str__(self):
return self.item_code
Create Form | Form To Formset
from django import forms
from django.forms import formset_factory
from . models import Item
class ItemForm(forms.ModelForm):
class Meta :
model = Item
fields = ['item_code','item_name','item_description','item_price','item_qty','item_picture']
widgets = {
'item_description':forms.TextInput()
}
ItemFormSet = formset_factory(ItemForm,extra=1)
Urls.py
from django.urls import path
from . import views
urlpatterns = [
path('',views.item_list,name='item_list'),
path('create/',views.item_create,name='item_create'),
path('item_update/<int:id>',views.item_update,name='item_update'),
path('item_delete/<int:id>',views.item_delete,name='item_delete'),
]
Views.py
from django.shortcuts import render,redirect
from django.http import HttpResponse
from . forms import ItemForm,ItemFormSet
from . models import Item
# Create your views here.
def item_create(request):
if request.method == 'POST' :
formset = ItemFormSet(request.POST,request.FILES,prefix = 'item',)
if formset.is_valid():
for form in formset :
instance = form.save(commit=False)
instance.save()
# if form.cleaned_data.get('item_price') is None:
# return render(request,'item/item_formset.html',{'formset':formset})
# else:
# form.save()
return redirect('item_list')
else :
formset = ItemFormSet(prefix='item')
return render(request,'item/item_formset.html',{'formset':formset})
def item_list(request):
items = Item.objects.all()
return render (request,'item/item_list.html',{'items':items})
def item_update(request,id):
item = Item.objects.get(id=id)
if request.method == 'POST':
form = ItemForm(request.POST, instance=item)
if form.is_valid():
form.save()
return redirect('item_list')
else:
form = ItemForm(instance=item)
return render(request,'item/item_form.html',{'form':form})
def item_delete(request,id):
item = Item.objects.get(id=id)
item.delete()
return redirect('item_list')
Template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
<form method="post" enctype="multipart/form-data" id="form-container">
{% csrf_token %}
{{ formset.management_form }}
<div class="table-responsive">
<table id="formset" class="table table-bordered border-primary table-sm ">
<thead class="table-dark">
<tr>
<th>Code</th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
<th>Qty</th>
<th>Picture</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for form in formset %}
<tr class="item-form">
<td>{{ form.item_code }}</td>
<td>{{ form.item_name }}</td>
<td>{{ form.item_description }}</td>
<td>{{ form.item_price }}</td>
<td>{{ form.item_qty }}</td>
<td>{{ form.item_picture }}</td>
<td>
<button class="btn btn-danger" onclick="removeRow(this)">-</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<button id="add-form" class="btn btn-info" type="button">+</button>
<input type="submit" class="btn btn-primary" value="submit">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script>
let container = document.querySelector("#form-container");
let addButton = document.querySelector("#add-form");
let totalForms = document.querySelector("#id_item-TOTAL_FORMS");
addButton.addEventListener('click', addForm);
function addForm() {
let itemForms = document.querySelectorAll(".item-form");
let lastForm = itemForms[itemForms.length - 1];
let newForm = lastForm.cloneNode(true);
let formNum = itemForms.length;
let formRegex = new RegExp(`item-(\\d+)-`, 'g');
let inputs = newForm.querySelectorAll('input');
inputs.forEach((input) => {
let newName = input.getAttribute('name').replace(formRegex, `item-${formNum}-`);
let newId = input.getAttribute('id').replace(formRegex, `id_item-${formNum}-`);
input.setAttribute('name', newName);
input.setAttribute('id', newId);
input.value = '';
});
let button = newForm.querySelector('button');
button.addEventListener('click', function() {
removeRow(this);
});
totalForms.value = formNum + 1;
container.querySelector('tbody').appendChild(newForm);
}
function removeRow(button) {
let row = button.parentNode.parentNode;
row.parentNode.removeChild(row);
let itemForms = document.querySelectorAll(".item-form");
totalForms.value = itemForms.length;
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<a href="{% url 'item_create' %}"> Create</a>
{% for item in items %}
<li>{{ item.item_name }} </li>
<li>{{ item.item_price }} </li>
<li> <a href="{% url 'item_update' item.id %}">Edit</a>
<a href="{% url 'item_delete' item.id %}" onclick="return confirm('Are you sure?');">Delete</a>
</li>
{% endfor %}
</body>
</html>
Last updated