Django CRUD Application

Sjlouji
The Startup
Published in
9 min readAug 21, 2020

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.

  1. Creating a Django Project and Database Initialization.
$ django-admin startproject curddjango
$ cd curddjango/
$ python3 manage.py runserver
Watching 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/#databases
DATABASES = {
'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 createView
urlpatterns = [
path('create',createView),
]

Now on navigating to the URL http://localhost:8000/create, you should see a page like this.

Add Employee Page

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, store
urlpatterns = [
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, index
urlpatterns = [
path('create',createView),
path('store',store,name='store'),
path('',index),
]

On visiting the http://localhost:8000/ URL, you should see something like this.

View Template

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, viewEmp
urlpatterns = [
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.

View Employee

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, viewEmp
urlpatterns = [
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, viewEmp
urlpatterns = [
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>
Updated Index.html UI

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

update.html UI

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, viewEmp
urlpatterns = [
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….

--

--

Sjlouji
The Startup

Software Engineer at @Pando. Developer | Writer. From ABC to the world of code.