Page 1
Last updated
Last updated
Django-admin startproject myproject
python manage.py startapp library
Add App With Django Project
INSTALLED_APPS = [
'library',
]
project urls.py
path('students/', include('library.urls')),
library/urls.py
from django.urls import path
from .views import author_create, author_list,author_update,author_delete
urlpatterns = [
path('author/create/', author_create, name='author_create'),
path('author/list/', author_list, name='author_list'),
path('author/update/<int:author_id>/', author_update, name='author_update'),
path('author/delete/<int:author_id>/', author_delete, name='author_delete'),
]
models.py
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
category = models.CharField(max_length=100,default='a')
def __str__(self):
return self.title
forms.py
from django import forms
from django.forms.models import inlineformset_factory
from .models import Author, Book
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
fields = ['name']
BookFormSet = inlineformset_factory(
Author,
Book,
fields=('title','category',),
extra=1,
can_delete=False,
min_num=1,
validate_min=True
)
views.py
from django.shortcuts import render, redirect,get_object_or_404
from .forms import AuthorForm, BookFormSet
from .models import Author,Book
def author_create(request):
if request.method == 'POST':
form = AuthorForm(request.POST)
formset = BookFormSet(request.POST)
if form.is_valid() and formset.is_valid():
author = form.save()
formset.instance = author
formset.save()
return redirect('author_list')
else:
form = AuthorForm()
formset = BookFormSet()
context = {
'form': form,
'formset': formset,
}
return render(request, 'library/author_create.html', context)
def author_list(request):
authors = Author.objects.all()
context = {'authors': authors}
return render(request, 'library/author_list.html', context)
def author_update(request, author_id):
author = get_object_or_404(Author, id=author_id)
if request.method == 'POST':
form = AuthorForm(request.POST, instance=author)
formset = BookFormSet(request.POST, instance=author)
if form.is_valid() and formset.is_valid():
form.save()
formset.save()
return redirect('author_list')
else:
form = AuthorForm(instance=author)
formset = BookFormSet(instance=author)
context = {
'form': form,
'formset': formset,
}
return render(request, 'library/author_update.html', context)
def author_delete(request, author_id):
author = get_object_or_404(Author, id=author_id)
if request.method == 'POST':
author.delete()
return redirect('author_list')
context = {
'author': author
}
return render(request, 'library/author_delete.html', context)
templates/library/author_create.html
<!DOCTYPE html>
<html>
<head>
<title>Create Author</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
$('.add-form').click(function() {
cloneForm($(this).data('form-prefix'));
});
$('.remove-form').click(function() {
removeForm($(this).data('form-prefix'));
});
function cloneForm(formPrefix) {
const formContainer = $('.form-container').last();
const totalForms = parseInt($('#id_' + formPrefix + '-TOTAL_FORMS').val());
const newForm = formContainer.clone();
newForm.find('input').val('');
newForm.find('select').val('');
newForm.find('input[type="hidden"]').remove();
newForm.find('label.error').remove();
formContainer.after(newForm);
newForm.find('input, select').each(function() {
updateFormElementIndex($(this), formPrefix, totalForms);
});
$('#id_' + formPrefix + '-TOTAL_FORMS').val(totalForms + 1);
}
function removeForm(formPrefix) {
const formContainer = $('.form-container');
if (formContainer.length > 1) {
formContainer.last().remove();
updateFormIndex(formPrefix);
}
}
function updateFormElementIndex(elem, formPrefix, formIndex) {
const idRegex = new RegExp(formPrefix + '-(\\d+|__prefix__)-');
const replacement = formPrefix + '-' + formIndex + '-';
elem.attr('id', elem.attr('id').replace(idRegex, replacement));
elem.attr('name', elem.attr('name').replace(idRegex, replacement));
elem.attr('for', elem.attr('for').replace(idRegex, replacement));
}
function updateFormIndex(formPrefix) {
const formContainer = $('.form-container');
formContainer.each(function(index) {
$(this).find('input, select').each(function() {
updateFormElementIndex($(this), formPrefix, index);
});
});
$('#id_' + formPrefix + '-TOTAL_FORMS').val(formContainer.length);
}
});
</script>
</head>
<body>
<h1>Create Author</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
{{ formset.management_form }}
<div class="formset-container">
{% for form in formset %}
<div class="form-container">
{{ form.as_table }}
{% if forloop.first %}
<button type="button" class="add-form" data-form-prefix="{{ formset.prefix }}">Add Book</button>
{% else %}
<button type="button" class="remove-form" data-form-prefix="{{ formset.prefix }}">Remove</button>
{% endif %}
</div>
{% endfor %}
</div>
<button type="submit">Save</button>
</form>
</body>
</html>
templates/library/author_update.html
<!DOCTYPE html>
<html>
<head>
<title>Update Author</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
$('.add-form').click(function() {
cloneForm($(this).data('form-prefix'));
});
$('.delete-form').click(function() {
deleteForm($(this).closest('.form-container'));
});
function cloneForm(formPrefix) {
const formContainer = $('.form-container').last();
const totalForms = parseInt($('#id_' + formPrefix + '-TOTAL_FORMS').val());
const newForm = formContainer.clone();
newForm.find('input').val('');
newForm.find('select').val('');
newForm.find('input[type="checkbox"]').prop('checked', false);
newForm.find('input[type="hidden"]').remove();
newForm.find('label.error').remove();
formContainer.after(newForm);
newForm.find('input, select').each(function() {
updateFormElementIndex($(this), formPrefix, totalForms);
});
$('#id_' + formPrefix + '-TOTAL_FORMS').val(totalForms + 1);
}
function deleteForm(formContainer) {
const totalForms = parseInt($('#id_' + formContainer.data('form-prefix') + '-TOTAL_FORMS').val());
if (totalForms > 1) {
formContainer.remove();
updateFormIndices(formContainer.data('form-prefix'));
$('#id_' + formContainer.data('form-prefix') + '-TOTAL_FORMS').val(totalForms - 1);
}
}
function updateFormElementIndex(elem, formPrefix, formIndex) {
const idRegex = new RegExp(formPrefix + '-(\\d+|__prefix__)-');
const replacement = formPrefix + '-' + formIndex + '-';
elem.attr('id', elem.attr('id').replace(idRegex, replacement));
elem.attr('name', elem.attr('name').replace(idRegex, replacement));
elem.attr('for', elem.attr('for').replace(idRegex, replacement));
}
function updateFormIndices(formPrefix) {
$('.form-container').each(function(index) {
updateFormElementIndex($(this), formPrefix, index);
});
}
});
</script>
</head>
<body>
<h1>Update Author</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
{{ formset.management_form }}
<div class="formset-container">
{% for form in formset %}
<div class="form-container">
{{ form.as_table }}
{% if forloop.last %}
<button type="button" class="add-form" data-form-prefix="{{ formset.prefix }}">Add Book</button>
{% else %}
<button type="button" class="delete-form">Remove Book</button>
{% endif %}
</div>
{% endfor %}
</div>
<button type="submit">Save</button>
</form>
</body>
</html>
templates/library/author_list.html
<!DOCTYPE html>
<html>
<head>
<title>Author List</title>
</head>
<body>
<h1>Author List</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for author in authors %}
<tr>
<td>{{ author.name }}</td>
<td>
<a href="{% url 'author_update' author.id %}">Edit</a>
<a href="{% url 'author_delete' author.id %}">Delete</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{% url 'author_create' %}">Add Author</a>
</body>
</html>
templates/library/author_delete.html
<!DOCTYPE html>
<html>
<head>
<title>Delete Author</title>
</head>
<body>
<h1>Delete Author</h1>
<p>Are you sure you want to delete the author "{{ author.name }}"?</p>
<form method="post">
{% csrf_token %}
<button type="submit">Delete</button>
<a href="{% url 'author_list' %}">Cancel</a>
</form>
</body>
</html>