Django CRUD Application
In this blog, let’s see what is CRUD and how to perform CRUD with Django. Also, visit my previous blogs if you have any problem with connecting Django and Databases. In this blog, I am performing CRUD functionality with PostgreSQL.

What is CRUD?
CRUD is Create, Read, Update, and Delete.
- Creating a Django Project and Database Initialization.
$ django-admin startproject curddjango
$ cd curddjango/
$ python3 manage.py runserverWatching for file changes with StatReloaderPerforming system checks...System check identified no issues (0 silenced).You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.Run 'python manage.py migrate' to apply them.August 21, 2020 - 07:14:32Django version 3.1, using settings 'curddjango.settings'Starting development server at http://127.0.0.1:8000/Quit the server with CONTROL-C.
After creating a project successfully, connect to any database of your wish. Here I am connecting with PostgreSQL. Initially, to connect with PostgreSQL, we should have an adapter. Install it with the command.
$ pip install postgres
After successful installation, open curddjango/settings.py
. Scroll to the database section to configure our database.
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databasesDATABASES = {
'default':
'ENGINE': 'django.db.backends.postgresql'
'NAME': 'django-curd' # Databaes Name
'USER': 'postgres' # User Name
'PASSWORD': 'admin' #Password
'HOST': '127.0.0.1'
'PORT': '5432'
}
}
Now create an app and register it in the settings.py
file.
$ python3 manage.py startapp curd
The above command creates an app named curd
in our project folder.

After creating, register the app in the settings.py
file.
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'curd', #Add your App name here
]
Now just migrate your project.
$ python3 manage.py migrateOperations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
2. Creating a model and migration:
Now create a new table named curd
in the database. Open curd/models.py
file to create our first model.
from django.db import models# Create your models here.
class Emp(models.Model):
emp_name = models.TextField()
emp_email = models.EmailField()
emp_mobile = models.TextField()
Now migrate your app.
$ python3 manage.py makemigrations
Migrations for 'curd':
curd/migrations/0001_initial.py
- Create model Emp$ python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, curd, sessions
Running migrations:
Applying curd.0001_initial... OK
3. Create
Template and View
Create a folder templates
in the main directory where we’ll be creating our views.
Now open curd/settings.py
file and scroll down to the Templates section and os.path.join(BASE_DIR,’templates’)
in the DIRS
. This will tell Django where our templates( UI) reside.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR,'templates') #Add this line
],
'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',
],
},
},
]
Now let's start creating our views.
Create a file named create.html
in the templates
folder.
<html><head><title>Create View</title><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"></head><body>
<div class="container" style="margin-top: 200px"><h2>Add Employee</h2>{% if messages %}
<ul class="messages">
{% for message in messages %}
<div class="alert alert-primary" role="alert">
{{ message }}
</div>
{% endfor %}
</ul>
{% endif %}<form method="POST">
<div class="form-group">
<label for="exampleInputEmail1">Employee Email</label>
<input type="email" class="form-control" id="emp_email" name="emp_email" placeholder="Enter email">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Employee Name</label>
<input type="text" class="form-control" id="emp_name" name="emp_name" placeholder="Employee Name">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Contact</label>
<input type="text" class="form-control" id="emp_mobile"
name="emp_mobile" placeholder="Contact">
</div>
<button type="submit" class="btn btn-primary">Add Employee</button>
</form>
</div><script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script><script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384 JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script></body>
</html>
Now in the curd/view.py
file, I am creating a function createView
that renders the create.html
page. I order to map or connect the view and the controller, I am creating a route or URL on the curd/urls.py
page.
curd/views.py
from django.shortcuts import render, redirect
from .models import Emp
from django.contrib import messages# Create your views here.
def createView(request):
return render(request,'create.html')
curd/urls.py
from django.conf.urls import url
from django.urls import path
from .views import createViewurlpatterns = [
path('create',createView),
]
Now on navigating to the URL http://localhost:8000/create, you should see a page like this.

Now I am creating another function named store
to handle the POST value from the form.
curd/view.py
from django.shortcuts import render, redirect
from .models import Emp
from django.contrib import messages# Create your views here.
def createView(request):
return render(request,'create.html')def store(request):
emp = Emp()
emp.emp_name = request.POST.get('emp_name')
emp.emp_email = request.POST.get('emp_email')
emp.emp_mobile = request.POST.get('emp_mobile')
emp.save()
messages.success(request, "Employee Added Successfully")
return redirect('/create')
Again now create a route to handle our POST request.
curd/urls.py
from django.conf.urls import url
from django.urls import path
from .views import createView, storeurlpatterns = [
path('create',createView),
path('store',store,name='store'),
]
Now add an action in our form to make a POST request.
templates/create.html
<form action={% url "store" %} method="POST"> #add actions in this line
<div class="form-group">
<label for="exampleInputEmail1">Employee Email</label>
<input type="email" class="form-control" id="emp_email" name="emp_email" placeholder="Enter email">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Employee Name</label>
<input type="text" class="form-control" id="emp_name" name="emp_name" placeholder="Employee Name">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Contact</label>
<input type="text" class="form-control" id="emp_mobile"
name="emp_mobile" placeholder="Contact">
</div>
<button type="submit" class="btn btn-primary">Add Employee</button>
</form>
If everything is fine, you should see the details entered in the form getting saved in the database.
4. Read
Template and View
Now create a new file index.html
in the templates folder.
<html><head><title> View Employee </title><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"></head><body><div class="container" style="margin-top: 200px">
<h1> View Employee </h1>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<div class="alert alert-primary" role="alert">
{{ message }}
</div>
{% endfor %}
</ul>
{% endif %}<table border="1" class="table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Mobile</th>
</tr>
</thead>
<tbody>
{% for emp_list in emp %}
<tr>
<td>{{ emp_list.emp_name }}</td>
<td>{{ emp_list.emp_email }}</td>
<td>{{ emp_list.emp_mobile }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div><script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script><script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script></body>
</html>
Now in the curd/view.py
I am creating a function index
that renders the index.html
page with all the employee data as an object. In order to map or connect the view with the controller, I am creating a route or URL in the curd/urls.py
page.
crud/view.py
def index(request):
emp = Emp.objects.all()
return render(request, 'index.html',{'emp':emp})
crud/urls.py
from django.conf.urls import url
from django.urls import path
from .views import createView, store, indexurlpatterns = [
path('create',createView),
path('store',store,name='store'),
path('',index),
]
On visiting the http://localhost:8000/ URL, you should see something like this.

To view each and every Employee Details, create another template named view.html
in the templates folder.
view.html
<html><head><title>View</title><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"></head><body>
<div class="container" style="margin-top: 200px">
<table class="table">
<tbody>
<tr>
<td>Employee Id</td>
<td>{{ emp.id }}</td>
</tr>
<tr>
<td>Employee Name</td>
<td>{{ emp.emp_name }}</td>
</tr>
<tr>
<td>Employee Email</td>
<td>{{ emp.emp_email }}</td>
</tr>
<tr>
<td>Contact</td>
<td>{{ emp.emp_mobile }}</td>
</tr>
</tbody>
</table>
</div><script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script><script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script></body>
</html>
Now I am creating a function named viewEmp
which finds the user with his/her id and returns his/her details to the view page as an object. After creating, I am mapping the view to an URL.
curd/viewEmp.py
def viewEmp(request,pk):
emp = Emp.objects.get(id = pk)
return render(request, 'view.html',{'emp':emp})
curd/urls.py
from django.conf.urls import url
from django.urls import path
from .views import createView, store, index, viewEmpurlpatterns = [
path('create',createView),
path('store',store,name='store'),
path('',index),
path('view/<int:pk>',viewEmp,name='viewEmp'),
]
Now call the view URL in the table row.
templates/index.html
<table border="1" class="table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Mobile</th>
<th>View</th>
</tr>
</thead>
<tbody>
{% for emp_list in emp %}
<tr>
<td>{{ emp_list.emp_name }}</td>
<td>{{ emp_list.emp_email }}</td>
<td>{{ emp_list.emp_mobile }}</td>
<td><a href="{% url 'viewEmp' emp_list.id %}">View</a></td>
</tr>
{% endfor %}
</tbody>
</table>
Now everything must be fine, and you should be able to view the Employee details as shown.

5. Delete
View
To delete an object from the table, I am creating a view named deleteEmp
in the curd/views.py
file and mapping it to an URL.
curd/view.py
def deleteEmp(request, pk):
emp = Emp.objects.get(id = pk)
emp.delete()
messages.success(request, "Employee Deleted Successfully")
return redirect('/')
curd/urls.py
from django.conf.urls import url
from django.urls import path
from .views import createView, store, index, deleteEmp, viewEmpurlpatterns = [
path('create',createView),
path('store',store,name='store'),
path('',index),
path('view/<int:pk>',viewEmp,name='viewEmp'),
path('delete/<int:pk>',deleteEmp,name='deleteEmp'),
]
Now call the delete URL in the index.html
template.
<table border="1" class="table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Mobile</th>
<th>Delete</th>
<th>View</th>
</tr>
</thead>
<tbody>
{% for emp_list in emp %}
<tr>
<td>{{ emp_list.emp_name }}</td>
<td>{{ emp_list.emp_email }}</td>
<td>{{ emp_list.emp_mobile }}</td>
<td><a href="{% url 'deleteEmp' emp_list.id %}">Delete</td>
<td><a href="{% url 'viewEmp' emp_list.id %}">View</a></td>
</tr>
{% endfor %}
</tbody>
</table>
6. Update
Template and view
To update an Employee in the table, I am creating another view for editing the user’s details.
curd/update.html
<html><head><title>Update View</title><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"></head><body>
<div class="container" style="margin-top: 200px">
<h2>Add Employee</h2>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<div class="alert alert-primary" role="alert">
{{ message }}
</div>
{% endfor %}
</ul>
{% endif %}
<form method="POST">
{% csrf_token %} <div class="form-group">
<label for="exampleInputEmail1">Employee Email</label>
<input type="email" class="form-control" id="emp_email" name="emp_email" placeholder="Enter email" value={{emp.emp_email}}>
</div> <div class="form-group">
<label for="exampleInputPassword1">Employee Name</label>
<input type="text" class="form-control" id="emp_name" name="emp_name" placeholder="Employee Name" value={{emp.emp_name}}>
</div> <div class="form-group">
<label for="exampleInputPassword1">Contact</label>
<input type="text" class="form-control" id="emp_mobile" name="emp_mobile" placeholder="Contact" value={{emp.emp_mobile}}>
</div> <button type="submit" class="btn btn-primary">Update Employee</button> </form></div><script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script><script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script></body>
</html>
I am creating a view to render this template and creating a route to map the view and template.
curd/updateView.py
def updateView(request,pk):
emp = Emp.objects.get(id = pk)
return render(request,'update.html',{'emp':emp})
curd/urls.py
from django.conf.urls import url
from django.urls import path
from .views import createView, store, index, deleteEmp, updateView, viewEmpurlpatterns = [
path('create',createView),
path('store',store,name='store'),
path('',index),
path('view/<int:pk>',viewEmp,name='viewEmp'),
path('delete/<int:pk>',deleteEmp,name='deleteEmp'),
path('update/<int:pk>',updateView, name='updateEmp'),
]
Again just call the Update URL in the index.html
file as shown.
templates/index.html
<table border="1" class="table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Mobile</th>
<th>Delete</th>
<th>Update</th>
<th>View</th>
</tr>
</thead>
<tbody>
{% for emp_list in emp %}
<tr>
<td>{{ emp_list.emp_name }}</td>
<td>{{ emp_list.emp_email }}</td>
<td>{{ emp_list.emp_mobile }}</td>
<td><a href="{% url 'deleteEmp' emp_list.id %}">Delete</td>
<td><a href="{% url 'updateEmp' emp_list.id %}">edit</a></td>
<td><a href="{% url 'viewEmp' emp_list.id %}">View</a></td>
</tr>
{% endfor %}
</tbody>
</table>

If everything is good, you should see the updated UI with Employee details on the text box.

Now create an Update function to update the Employee details.
curd/views.py
def update(request,pk):
print('in')
emp = Emp.objects.get(id = pk)
emp.emp_name = request.POST.get('emp_name')
emp.emp_email = request.POST.get('emp_email')
emp.emp_mobile = request.POST.get('emp_mobile')
emp.save()
messages.success(request, "Employee Update Successfully")
return redirect('/')
curd/urls.py
from django.conf.urls import url
from django.urls import path
from .views import createView, store, index, deleteEmp, updateView, update, viewEmpurlpatterns = [
path('create',createView),
path('store',store,name='store'),
path('',index),
path('view/<int:pk>',viewEmp,name='viewEmp'),
path('delete/<int:pk>',deleteEmp,name='deleteEmp'),
path('update/<int:pk>',updateView, name='updateEmp'),
path('edit/<int:pk>',update, name='edit'),
]
Now add an action in the form to make a POST request
<form action={% url 'edit' emp.id %} method="POST">
{% csrf_token %}
<div class="form-group">
<label for="exampleInputEmail1">Employee Email</label>
<input type="email" class="form-control" id="emp_email" name="emp_email" placeholder="Enter email" value={{emp.emp_email}}>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Employee Name</label>
<input type="text" class="form-control" id="emp_name" name="emp_name" placeholder="Employee Name" value={{emp.emp_name}}>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Contact</label>
<input type="text" class="form-control" id="emp_mobile" name="emp_mobile" placeholder="Contact" value={{emp.emp_mobile}}>
</div>
<button type="submit" class="btn btn-primary">Update Employee</button>
</form>
Now you are good to go.
Feel free to contact me for any queries regarding this blog.
Email: sjlouji10@gmail.com
Linkedin: https://www.linkedin.com/in/sjlouji/
I am adding Github URL of this blog: https://github.com/sjlouji/-CURD-Django-Medium.git
Happy coding….