CRUD with Django and Ajax
In this post we will learn to CRUD with Django and Ajax. Ajax will help to submit the Django forms without the page being refreshed. We will also learn to display, edit and delete content with refreshing the page.
Table of Contents
- Initial Setup
- Question_Answer_app
- Create a Model
- SuperAdmin
- Create the Form
- Create views and urls to display the form and data
- Templates for home
- Create and Read with Ajax
- Deleting the Entries with help of AJAX
- Editing the content
- The final output
Initial Setup
#terminal
mkdir Django_Crud_Ajax
cd Django_Crud_Ajax
python3 -m venv venv
source venv/bin/activate
gh repo create
#then walk through
#Terminal
cd Django_Crud_With_Ajax
#Install django
pip install django
django-admin startproject Django_Crud_With_Ajax
cd Django_Crud_With_Ajax
python manage.py runserver
Question_Answer_app
#terminal
python manage.py startapp Question_Answer_app
#open vs code with
code .
Create a Model
Add the following lines of code to the models.py file of Question_Answer_app
from django.db import models
# Create your models here.
class QuestionsAnswer(models.Model):
question = models.TextField()
answer = models.TextField()
def __str__(self):
return self.question
Add the application to the django project “Django_Crud_With_Ajax” by editing the settings.py file.
.................................
# Application definition
INSTALLED_APPS = [
'Question_Answer_app',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
...................................
Make migrations and migrate
#terminal
python manage.py makemigrations
python manage.py migrate
SuperAdmin
#terminal
python manage.py createsuperuser
To add model to admin edit the admin.py as follow.
from django.contrib import admin
from .models import QuestionsAnswer
# Register your models here.
@admin.register(QuestionsAnswer)
class QuestionAdmin(admin.ModelAdmin):
list_display = ('id','question','answer')
Run the server and visit http://127.0.0.1:8000/admin/
Login with your superuser credentials
Add a question and an answer.
Create the Form
Create a new forms.py within your app and fill it with the following code.
from django import forms
from .models import QuestionsAnswer
class QuestionForm(forms.ModelForm):
class Meta:
model = QuestionsAnswer
fields = ['question','answer']
Create views and urls to display the form and data
Edit the views.py file of your application as follow.
from django.shortcuts import render,redirect
from .models import QuestionsAnswer
from .forms import QuestionForm
# Create your views here.
def home(request):
all_questions = QuestionsAnswer.objects.all()
if request.method == 'POST':
form = QuestionForm(request.POST)
if form.is_valid():
form.save()
print("Form submitted")
return redirect('home')
else:
form = QuestionForm()
data = {'form':form,'questions':all_questions}
return render(request,"home.html",data)
Edit the urls.py of your django-project as follows.
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path("que/",include("Question_Answer.urls")),
]
Create the urls.py file in your application and add the following line of code.
from django.urls import path
from .import views
urlpatterns = [
path("",views.home,name="home"),
]
Templates for home
Create a folder named templates within your application. Within the template folder create file name “home.html”.
Add following lines of code to home.html.
<!DOCTYPE html>
<html>
<head>
<title>
This is home page
</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
{{form.as_p}}
<button type="submit">Submit</button>
</form>
<ul id="que-list">
{% for q in questions %}
<li>
<h3>
{{q.question}}
</h3>
<p>
{{q.answer}}
</p>
<input type="button" data-qid="{{q.id}}"
class="btn-edit" value="Edit"/>
<input type="button" data-qid="{{q.id}}"
class="btn-del"
value="Delete"/>
</li>
{% endfor %}
</ul>
</body>
</html>
So, far we can submit the form but our page reloads after we submit the form. We want to submit the form and show the latest content without reloading the page. For this we will be using AJAX.
Create and Read with Ajax
Change the templates/home.html as follow.
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>
This is home page
</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</script>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
{{form.as_p}}
<button type="submit" id="btnsave">Submit</button>
</form>
<ul id="que-list">
{% for q in questions %}
<li>
<h3>
{{q.question}}
</h3>
<p>
{{q.answer}}
</p>
<input type="button" data-qid="{{q.id}}"
class="btn-edit" value="Edit"/>
<input type="button" data-qid="{{q.id}}"
class="btn-del"
value="Delete"/>
</li>
{% endfor %}
</ul>
<script>
$("#btnsave").click(function(){
console.log("Save button clicked");
});
</script>
</body>
</html>
Edit the views.py
from django.shortcuts import render,redirect
from django.http import JsonResponse
from .models import QuestionsAnswer
from .forms import QuestionForm
# Create your views here.
def home(request):
form = QuestionForm()
all_questions = QuestionsAnswer.objects.all()
data = {'form':form,'questions':all_questions}
return render(request,"home.html",data)
def save_data(request):
if request.method == "POST":
form = QuestionForm(request.POST)
if form.is_valid():
que = request.POST['question']
ans = request.POST['answer']
question = QuestionsAnswer(question=que,answer=ans)
question.save()
question_data = list(QuestionsAnswer.objects.values())
return JsonResponse({"status":'Save','question_data':question_data})
else:
return JsonResponse({'status':0})
edit application level urls.py
from django.urls import path
from .import views
urlpatterns = [
path("",views.home,name="home"),
path("save/",views.save_data,name="save"),
]
Output so Far
Add more code to home.html
<script>
$("#btnsave").click(function(){
console.log("Save button clicked");
output = "";
let que = $("#id_question").val();
let ans = $("#id_answer").val();
let csr = $("input[name=csrfmiddlewaretoken]").val();
que_data = {question:que, answer:ans,csrfmiddlewaretoken:csr}
console.log(que_data);
console.log(csr);
});
</script>
Adding AJAX
<script>
$("#btnsave").click(function(){
console.log("Save button clicked");
output = "";
let que = $("#id_question").val();
let ans = $("#id_answer").val();
let csr = $("input[name=csrfmiddlewaretoken]").val();
que_data = {question:que, answer:ans,csrfmiddlewaretoken:csr}
console.log(que_data);
console.log(csr);
$.ajax({
url:"{% url 'save' %}",
method:"POST",
data:que_data,
dataType:"json",
success:function(data){
console.log("data saved");
x = data.question_data
console.log(x.length);
if(data.status == 'Save'){
console.log("data saved again");
for(i=0; i<x.length;i++){
console.log(x[i].question);
output += '<li><h3>' + x[i].question + '</h3><p>'+x[i].answer+'</p></li><input type="button" class="btn btn-edit" value="Edit" data-sid='+x[i].id+"><input type='button' class='btn btn-del' value='Delete' data-sid="+x[i].id+">"
}
$("#que-list").html(output) ;
$("form")[0].reset();
location.reload();
}
if(data.status ==0){
console.log("Unable to save form");
$("form")[0].reset();
location.reload();
}
}
});
});
</script>
Now the data will be added with the page being reloaded.
Deleting the Entries with help of AJAX
Add the following code to home.html
<script>
//create
$("#btnsave").click(function(){
console.log("Save button clicked");
output = "";
let que = $("#id_question").val();
let ans = $("#id_answer").val();
let csr = $("input[name=csrfmiddlewaretoken]").val();
que_data = {question:que, answer:ans,csrfmiddlewaretoken:csr}
console.log(que_data);
console.log(csr);
$.ajax({
url:"{% url 'save' %}",
method:"POST",
data:que_data,
dataType:"json",
success:function(data){
console.log("data saved");
x = data.question_data
console.log(x.length);
if(data.status == 'Save'){
console.log("data saved again");
for(i=0; i<x.length;i++){
console.log(x[i].question);
output += '<li><h3>' + x[i].question + '</h3><p>'+x[i].answer+'</p></li><input type="button" class="btn btn-edit" value="Edit" data-sid='+x[i].id+"><input type='button' class='btn btn-del' value='Delete' data-sid="+x[i].id+">"
}
$("#que-list").html(output) ;
$("form")[0].reset();
location.reload();
}
if(data.status ==0){
console.log("Unable to save form");
$("form")[0].reset();
location.reload();
}
}
});
});
//delete data
$(document).on("click",".btn-del",function(){
console.log("Delete Button Clicked");
let id = $(this).attr("data-qid");
let csr = $("input[name=csrfmiddlewaretoken]").val();
console.log(id);
mydata = {qid:id,csrfmiddlewaretoken:csr};
console.log(mydata);
mythis = this;
$.ajax({
url:"{%url 'delete' %}",
method:"POST",
data:mydata,
success:function(data){
if(data.status==1){
console.log("Data Deleted Successfully");
location.reload();
}
if(data.status == 0){
console.log("Unable to delete data");
}
},
});
});
</script>
Now add following function to views.py
#Delete Data
def delete_data(request):
if request.method == "POST":
id = request.POST.get("qid")
pi = QuestionsAnswer.objects.get(pk=id)
pi.delete()
return JsonResponse({'status':1})
else:
return JsonResponse({'status':0})
And add the following code to urls.py
from django.urls import path
from .import views
urlpatterns = [
path("",views.home,name="enroll"),
path("save/",views.save_data,name="save"),
path("delete/",views.delete_data,name="delete"),
]
Editing the content
First edit home.html form part as follow.
<form action="" method="post">
{% csrf_token %}
<input type="hidden" name="queid" id="queid"/>
{{form.as_p}}
<button type="submit" id="btnsave">Submit</button>
</form>
This highlighted part will help us to edit the content. Without this the edit content will be added to database as new content.
Now, add the following lines of code within <script> … </script> of the home.html.
<script>
................................................
$(document).on('click','.btn-edit',function(){
console.log("Edit button clicked");
let id = $(this).attr("data-qid");
let csr = $("input[name=csrfmiddlewaretoken]").val()
console.log(id)
mydata = {qid:id,csrfmiddlewaretoken:csr};
console.log(mydata);
$.ajax({
url:"{%url 'edit'%}",
method:"POST",
data:mydata,
dataType:"json",
success:function(data){
console.log(data);
$("#queid").val(data.id);
$("#id_question").val(data.question);
$("#id_answer").val(data.answer);
},
});
});
</script>
Add the following function to views.py
#Edit Data
def edit_data(request):
if request.method == "POST":
id = request.POST.get('qid')
q = QuestionsAnswer.objects.get(pk=id)
data = {"id":q.id,
"question":q.question,
"answer":q.answer}
return JsonResponse(data)
Add following codes to urls.py file of the application.
from django.urls import path
from .import views
urlpatterns = [
path("",views.home,name="enroll"),
path("save/",views.save_data,name="save"),
path("delete/",views.delete_data,name="delete"),
path("edit/",views.edit_data,name="edit"),
]
The edited content is saved as the new entry. To deal with this we need to edit our save_data(request) function of views.py as follow.
def save_data(request):
if request.method == 'POST':
form = QuestionForm(request.POST)
if form.is_valid():
qid= request.POST.get('queid')
print("******************")
print(qid)
que = request.POST['question']
ans = request.POST['answer']
#case when qid is empty, that is new entry
if(qid==""):
question = QuestionsAnswer(question=que,answer=ans)
#case when qid is not empty, editing old entry
else:
question = QuestionsAnswer(id=qid,question=que,answer=ans)
question.save()
question_data = list(QuestionsAnswer.objects.values())
return JsonResponse({'status':'Save','question_data':question_data})
else:
return JsonResponse({'status':0})
Now, edit the home.html code as follow.
<script>
//create
$("#btnsave").click(function(){
console.log("Save button clicked");
output = "";
let quesid = $("#queid").val();
let que = $("#id_question").val();
let ans = $("#id_answer").val();
let csr = $("input[name=csrfmiddlewaretoken]").val();
que_data = {queid:quesid,question:que, answer:ans,csrfmiddlewaretoken:csr}
console.log(que_data);
console.log(csr);
$.ajax({
url:"{% url 'save' %}",
method:"POST",
data:que_data,
dataType:"json",
success:function(data){
console.log("data saved");
x = data.question_data
console.log(x.length);
if(data.status == 'Save'){
console.log("data saved again");
for(i=0; i<x.length;i++){
console.log(x[i].question);
output += '<li><h3>' + x[i].question + '</h3><p>'+x[i].answer+'</p></li><input type="button" class="btn btn-edit" value="Edit" data-sid='+x[i].id+"><input type='button' class='btn btn-del' value='Delete' data-sid="+x[i].id+">"
}
$("#que-list").html(output) ;
$("#queid").val("");
$("form")[0].reset();
location.reload();
}
if(data.status ==0){
console.log("Unable to save form");
$("form")[0].reset();
location.reload();
}
}
});
});