Simple Django CRUD App
JMG
Posted on December 30, 2020
Hello, if you are just beginning to learn Django, this is a good example of simple CRUD (Create Retrieve Update and Delete) operations.
In this tutorial, we are going to create a simple application that allows us to create, retrieve, update and delete a student.
Steps
1.Create new project
2.Create the models
3.Create a form
4.Add templates folder
5.Create the views
1.Create new project
Create a new django project (preferably in a virtual environment) using django-admin startproject students-crud
proceed to create an app students using python manage.py startapp students
.
Register the app in your settings.py file.
2.Create the models
We are going to have 2 models, Stream model and Student model.
Register the app in your settings.py file.
Open your students app's models.py file. This is where we will create our models, using the code below:
class Stream(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return f'{self.name}'
class Student(models.Model):
name = models.CharField(max_length= 50)
description = models.TextField()
joindate = models.DateTimeField(auto_now_add = True)
reg_no = models.CharField(max_length=100, unique=True)
stream = models.ForeignKey(Stream, on_delete=models.CASCADE,
related_name="students")
def __str__(self):
return f'{self.name} reg {self.reg_no}'
Navigate to admin.py and register your 2 models as follows:
from students.models import Student, Stream
# Register your models here.
admin.site.register(Student)
admin.site.register(Stream)
3.Create a form
In your app's folder, create a new file and name it forms.py.
Add the following code to your file:
from django import forms
from .models import Student
class CreateStudentForm(forms.ModelForm):
class Meta:
model = Student
fields = "__all__"
4.Create a folder for our templates
To make it easier to access our templates, we shall create a single folder named templates that will contain all of our templates.
Navigate to your settings.py , locate your Templates array and replace it with the following:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Navigate to the root folder of your project and create a folder named templates
5.Create Views
Navigate to your views.py file and we'll start writing code.
We are going to use function based views for this.
First, we create a view to create a student instance (object).
This will also be the view for our landing page.
To do this, we need to import the form we created in forms.py.
Include this import from .forms import CreateStudentForm
Here now goes the view:
def CreateStudent(request):
if request.method == "POST":
form = CreateStudentForm(request.POST)
if form.is_valid():
form.save()
form = CreateStudentForm()
else:
form = CreateStudentForm()
students = Student.objects.all().order_by("-id")
context = {'form':form, 'students':students}
return render(request, 'home.html', context)
We want to display our students starting with the last added, hence order_by("-id") in
students = Student.objects.all().order_by("-id")
Create a file index.html in the templates we created in the previous step.
This template will show a form for creating new students and also list the existing students in a table.
For each student instance or record, you will be able to view or delete it.
I have added bootstrap to it to make it look better.
Your index.html should be like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx"
crossorigin="anonymous"></script>
<title>Good Schools | Home</title>
</head>
<body>
<div>
<form method="post">
{% csrf_token %}
{{form.as_p}}
<button type="submit">Submit</button>
</form>
</div>
<!-- list of students -->
<div>
<h4 class="text-center mb-3 mt-3">Students List</h4>
<div class="table-responsive-sm">
<table class="table table-hover">
<thead class="thead-light">
<tr>
<th scope="col">Name</th>
<th scope="col">Reg No.</th>
<th scope="col">Stream</th>
<th scope="col">Description</th>
<th scope="col">Join Date</th>
<th scope="col">View</th>
<th scope="col">Delete</th>
</tr>
</thead>
<tbody>
{% for student in students %}
<tr>
<td class="text-capitalize">{{student.name}}</td>
<td>{{student.reg_no}}</td>
<td>{{student.stream}}</td>
<td class="text-capitalize">{{student.description}}</td>
<td>{{student.joindate}}</td>
<td>
<a role="button" class="btn btn-sm btn-outline-success"
href="{% url 'std_detail' reg=student.reg_no %}">View</a>
</td>
<td>
<a role="button" class="btn btn-sm btn-outline-danger" href="{% url 'delete' id=student.id %}">Delete</a>
<!-- <button class="btn btn-sm btn-outline-danger">Delete</button></td> -->
</tr>
{% empty %}
<span class="text-center">No students to show</span>
{% endfor %}
</tbody>
</table>
</div>
</div>
</body>
As mentioned above, we want to view a specific student.
To achieve this, we need to create another view.
We are going to fetch a student from the database by using their reg_no as used in our Student model.
This same view will be used to update a student instance, hence passing the student instance will pre-populate the form.
def GetStudent(request, **kwargs):
reg = kwargs.get('reg')
student = get_object_or_404(Student, reg_no=reg)
if request.method == "POST":
form = CreateStudentForm(request.POST, instance=student)
if form.is_valid():
form.save()
else:
form = CreateStudentForm(instance=student)
context = {'student':student, 'form': form}
return render(request, 'std_detail.html', context )
Our std_detail.html will look like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
<title>Good Schools | Student Detail | {{student.reg_no}}</title>
</head>
<body>
<div class="big-box container-fluid d-flex justify-content-center align-items-center">
<div class="container mt-4 mb-5">
<h4 class="text-center text-capitalize">{{student.name}}'s Profile</h4>
<form class="mt-3" method="post">
{% csrf_token %}
<div class="form-group">
<div class="row">
<div class="col">
<label>Name:</label>
{{form.name}}
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col">
<label>Reg No.</label>
{{form.reg_no}}
</div>
<div class="col">
<label>Stream:</label>
{{form.stream}}
</div>
</div>
</div>
<div class="form-group">
<label>Description:</label>
{{form.description}}
</div>
<div class="form-group">
<div class="row">
<div class="col d-flex justify-content-center">
<button class="btn btn-warning btn-block text-white w-50">Update</button>
</div>
<div class="col d-flex justify-content-center">
<a href="{% url 'delete' id=student.id %}" role="button" class="btn btn-danger btn-block text-white w-50">Delete</a>
</div>
</div>
</div>
</form>
</div>
</div>
<div class="container d-flex justify-content-center">
<a href="{% url 'create_student' %}" role="button" class="btn btn-outline-primary btn-block w-25">All Students</a>
</div>
</body>
</html>
To delete a student, we will also use their reg_no to fetch them, then proceed to delete them.
Here is the view:
def DeleteStudent(request, **kwargs):
reg = kwargs.get('reg')
student = Student.objects.get(reg_no=reg)
student.delete()
return redirect('home')
We now need to define our urls so that we can view and access what we have done.
Create a urls.py file in your app and include the following:
from django.urls import path
from .views import CreateStudent,GetStudent, Delete
urlpatterns = [
path('', CreateStudent, name='create_student'),
path('std_detail/<str:reg>/', GetStudent, name='std_detail'),
path('delete/<int:id>', Delete, name='delete'),
Head to your project's url.py and add the following:
from django.urls import path,include
urlpatterns = [
path('', include("home.urls")),
path('admin/', admin.site.urls),
]
That's it! Migrate your project and run your server.
You now have your simple CRUD application.
Posted on December 30, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.