Hello World, Welcome to ProjectsPlaza.com. Today I am going to discuss how to add and update data with ModelForm in Django 3. In this tutorial, We will create a simple todo application with add, update, and delete functionality. I have divided this tutorial into the following steps:
- Create a learning project
- Create todo app
- Create todo Model
- Create add and update form from todo model
- Delete todo item
- Add bootstrap 4 in the templates
This is a small but full-fledged application built with Django 3 and bootstrap 4. You can download source code from GitHub.
I have assumed that you have installed Python 3 and Django 3 on your system
Create a learning project
- Run this command to create learning projects
django-admin startproject learning && cd learning
Create todo app
- Run this command to create todo application
py manage.py startapp todo
- Add todo app in learning/learning/settings.py file
INSTALLED_APPS = [ ... 'todo', ]
- Add URL routing in learning/learning/urls.py file
from django.urls import path,include urlpatterns = [ path('admin/', admin.site.urls), path('todo/',include('todo.urls')), ]
- Create urls.py file in the todo app with the following code.
from django.urls import path from . import views urlspatterns=[ path('',views.all,name='all') ]
In the above code, you can see we have imported all method from views.py file ( we will create in the next section).
- Create all method in views.py file in the todo app.
from django.shortcuts import render def all(request): return render(request,'all.html')
In the above code, we are rendering all.html file. The render function will search this file in todo/templates folder. So let’s create this file in templates folder and add the following code.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>All Todo Items</title> </head> <body> <div class="container"> <h3>All Items</h3> <p><a href="/todo/add">Add Item >></a></p> <table border="1" cellpadding="5" cellspacing="3"> <tr> <th>Title</th> <th>Status</th> <th>Action</th> </tr> <tr> <td>Item 1</td> <td>True</td> <td> <a href="#">Edit</a> | <a href="#">Delete</a> </td> </tr> <tr> <td>Item 2</td> <td>False</td> <td> <a href="#">Edit</a> | <a href="#">Delete</a> </td> </tr> </table> </div> </body> </html>
- Run the server with the command
py manage.py runserver
- You will see the following screen when you access http://127.0.0.1:8000/todo/
Create Todo Model
- Open models.py and add the following code.
class Todo(models.Model): title=models.CharField(max_length=200) status=models.BooleanField(default=False) def __str__(self): return self.title
- Stop the server with
ctrl+c
and run the following commands. py manage.py makemigrations && py manage.py migrate
After running the above command, The above code will create a todo table with the title and status column.
Create add and update form from todo model
In this step, we will create forms.py file in todo app folder with the following code. This code will generate a form with a defined field in the todo model.
from django.forms import ModelForm from .models import Todo class todoAddForm(ModelForm): class Meta: model=Todo fields=('title','status')
- Create add method in views.py file.
# Add Method def add(request): addForm=todoAddForm() return render(request,'add.html',{ 'form':addForm })
- Create add.html in the templates folder with the following code.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>All Todo Items</title> </head> <body> <div class="container"> <h3>Add Item</h3> <p><a href="/todo"><< All Items</a></p> <form method="post" action="."> {%csrf_token%} <table border="1" cellpadding="5" cellspacing="3"> {{form.as_table}} <tr> <td colspan="2"> <button>Submit</button> </td> </tr> </table> </form> </div> </body> </html>
- Add the following URL path in todo/urls.py file.
urlpatterns=[ ... path('add',views.add,name='add'), ]
- After running your server, you will see the following screen at
http://127.0.0.1:8000/todo/add
Now we will create code for adding data in the database.
- Replace the add method code in views.py file with the following code.
def add(request): addForm=todoAddForm() if request.method=='POST': todoAdd=todoAddForm(request.POST) if todoAdd.is_valid(): todoAdd.save() messages.success(request, 'Data has been added.') return redirect('/todo/add') return render(request,'add.html',{ 'form':addForm })
The above code will validate the form and save data in the database then redirect to add form.
Please add the following code at the top of the file for messages and redirect.
from django.shortcuts import redirect from django.contrib import messages
We have implemented the add functionality. Now we will create update functionality. Firstly we will show all the added items in all.html.
- Replace all method function in views.py file with the following code.
from .models import Todo # All Items def all(request): items=Todo.objects.all() return render(request,'all.html',{ 'items':items })
- Now replace the table content with following code in all.html
<table border="1" cellpadding="5" cellspacing="3"> <tr> <th>Title</th> <th>Status</th> <th>Action</th> </tr> {% for item in items %} <tr> <td>{{item.title}}</td> <td>{{item.status}}</td> <td> <a href="/todo/item/edit/{{item.id}}">Edit</a> | <a onclick="return confirm('Are you sure to delete this code?')" href="/todo/item/delete/{{item.id}}">Delete</a> </td> </tr> {% endfor %} </table>
After applying these changes, Data will be coming from a database with a dynamic link for edit and delete. Try to add some items. Now we will work on edit functionality. First of all, we create a method and template for update todo item.
- Create an update method in views.py file in the todo app.
# Update Method def update(request,id): item=Todo.objects.get(pk=id) updateForm=todoAddForm(instance=item) if request.method=='POST': todoAdd=todoAddForm(request.POST,instance=item) if todoAdd.is_valid(): todoAdd.save() messages.success(request, 'Data has been updated.') return redirect('/todo/item/edit/'+str(id)) return render(request,'update.html',{ 'form':updateForm, 'item':item })
- Create update.html template in templates folder with the following code.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>All Todo Items</title> </head> <body> <div class="container"> <h3>Update Item</h3> <p><a href="/todo"><< All Items</a></p> {% if messages %} {% for message in messages %} <p class="text-success">{{ message }}</p> {% endfor %} {% endif %} <hr/> <form method="post" action="/todo/item/edit/{{item.id}}"> {% csrf_token %} <table border="1" cellpadding="5" cellspacing="3"> {{form.as_table}} <tr> <td colspan="2"> <button>Submit</button> </td> </tr> </table> </form> </div> </body> </html>
- Update todo/urls.py with the following code.
urlpatterns=[ ... path('item/edit/<int:id>',views.update,name='update'), ]
Now, When you will click on the edit link then you will able to change the data of that item and redirect on update form. Till now we have completed our add and update functionality with the Django model form feature. In the next section, we will create delete functionality.
Delete Functionality
- Add the delete method in views.py file
# Delete def delete(request,id): Todo.objects.filter(id=id).delete() return redirect('/todo')
- Add the following URL route in todo/urls.py file
urlpatterns=[ ... path('item/delete/<int:id>',views.delete,name='delete'), ]
Now, When you click on the delete link, it will delete data and redirect on all items page.
Add Bootstrap
Add the following link tag in every template in before </head> tag
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" />
- Add this class in table tag in every template
table table-bordered
- Add this class in Submit button in add and update template
btn btn-primary
I hope you enjoyed this tutorial. please add your feedback in the comment section :).