While Django’s template engine is easy to use, it lacks some advanced features found in other templating engines, such as full programming logic, which can lead to limitations in complex UI designs.
Author: saqibkhan
-
Update Data
Django ORM uses the Active Record pattern for the interaction between a model class and its mapped database table. An instance of the model class corresponds to a single row in the table. Any of the attributes of the object results in updating the corresponding row.
In this chapter, we will focus on the different ways available in Django to update an already existing row in a relational database.
We shall use the Dreamreal model as given below for the exercise −
classDreamreal(models.Model): website = models.CharField(max_length=50) mail = models.CharField(max_length=50) name = models.CharField(max_length=50) phonenumber = models.IntegerField()def__str__(self):return"Website: {} Email: {} Name: {} Ph.: {}".format(self.website, self.mail, self.name, self.phonenumber)It is assumed that you have already performed the migrations and added a few objects in the model.
Update Object From Shell
Django has a useful feature with which you can invoke a Python shell inside the Django project’s environment. Use the shell command with the manage.py script −
python manage.py shellIn front of the Python prompt, import the Dreamreal model −
>>>from myapp.models import DreamrealThe model.objects attribute returns the model Manager, and its all() method returns a QuerySet. We can limit the objects in the set by applying the filter.
To return the object with its primary key as 2, use the following statement −
obj = Dreamreal.objects.filter(pk =2)The model class has the get() instance method with which we can change the value of one or more attributes.
obj.update(f1=v1, f2=v2,...)Let us update the name of the object with “pk = 2” −
obj.update(name='example')The model manager also has a get() method that fetches a single instance corresponding to the given keyword argument −
obj = Dreamreal.objects.get(phonenumber =2376970)We can use a simple assignment to update an attribute. Let us change the phone number −
obj.phonenumber =24642367570To make the change persistent, you need to call the save() method −
obj.save()Perform Update Operation by Calling a View Function
Let us now perform the update operation by calling a view function. Define the update() function in views.py file. This function receives the primary key as the argument from its mapped URL.
from django.shortcuts import render from django.http import HttpResponse from myapp.models import Dreamreal defupdate(request, pk): obj = Dreamreal.objects.get(pk=pk) obj.name="admin" obj.save()return HttpResponse("Update successful")We also need to register this view in the urls.py file by adding a new path −
from django.urls import path from.import views from.views import DRCreateView, update urlpatterns =[ path("", views.index, name="index"), path("addnew/", views.addnew, name='addnew'), path("update/<int:pk>", views.update, name='update'),]Run the Django server and visit the URL http://localhost:8000/myapp/update/2. The browser emits the update success message.
Instead of using the hard-coded values as in the above example, we would like the data to be accepted from the user. We need to populate a HTML form with the object data corresponding to the primary key.
Modify the update() View Function
Modify the update() view function as shown −
from django.shortcuts import render from django.http import HttpResponse from myapp.models import Dreamreal defupdate(request, pk): obj = Dreamreal.objects.get(pk=pk)if request.method =="POST":
obj = Dreamreal.objects.get(pk=pk) context ={"obj":obj}return render(request,"myform.html", context)ws = request.POST['website'] mail = request.POST['mail'] nm = request.POST['name'] ph = request.POST['phonenumber'] obj.name = nm obj.phonenumber = ph obj.save()return HttpResponse("<h2>Record updated Successfully</h2>")We need to populate the form elements with the values of object attributes with the template variables.
Modify the myform.html script as follows −
<html><body><form action="../update/{{ obj.pk }}" method="post">{% csrf_token %} <p><label for="website">WebSite: </label><input id="website" type="text" value = {{ obj.website }} name="website" readonly></p><p><label for="mail">Email: </label><input id="mail" type="text" value = {{ obj.mail }} name="mail" readonly></p><p><label for="name">Name: </label><input id="name" type="text" value = {{ obj.name }} name="name"></p><p><label for="phonenumber">Phone Number: </label><input id="phonenumber" type="text" value = {{ obj.phonenumber }} name="phonenumber"></p><input type="submit" value="Update"></form></body></html></code></pre>Visiting the URL http://localhost:8000/myapp/update/2 renders a HTML form pre-populated with the data belonging to pk=2. User can update the name and phonenumber fields.
Using ModelForm for Update
Next, we shall use the ModelForm class to render a HTML form with its input elements corresponding to the model field types. Let use the DereamrealForm class that inherits the Modelform
from django import forms from.models import Dreamreal classDreamrealForm(forms.ModelForm):classMeta:model = Dreamreal fields ="__all__"def__init__(self,*args,**kwargs):super(DreamrealForm, self).__init__(*args,**kwargs) self.fields['website'].widget = forms.TextInput(attrs={'readonly':'readonly'}) self.fields['mail'].widget = forms.TextInput(attrs={'readonly':'readonly'})</code></pre>Note − Here, we have set the readonly property of the website and mail fields in the class constructor.
The View function update() receives the primary key argument from the URL as before. When this function is called with POST method, the form data is used to update the existing object.
When the GET method is used, Django fetches the object corresponding to the primary key, and uses its attributes to populate the HTML form −
defupdate(request, pk): obj = Dreamreal.objects.get(pk=pk)if request.method =="POST":
obj = Dreamreal.objects.get(pk=pk) context ={"obj": DreamrealForm(instance=obj),"pk": obj.pk}return render(request,"myform.html", context)form = DreamrealForm(request.POST)if form.is_valid(): form.save()return HttpResponse("<h2>Record updated Successfully</h2>")Visit the http://localhost:8000/myapp/update/1 URL to display the HTML form with its fields filled with the record with pk=1. You can change the values and submit for the corresponding object to be updated.

The UpdateView Class
Django defines a collection of generic view classes. The UpdateView class is specially designed for performing the INSERT query operation.
We define a subclass of UpdateView class and set its template_name property to myform.html that we have already created.
Add the following code in views.py file −
from django.views.generic.edit import UpdateView classDRUpdateView(UpdateView): model = Dreamreal fields ='__all__' template_name ="myform.html" success_url ="../success/"To register this view, we need to update the urls.py file for our app. Note that, to register a generic view, we use the as_view() method.
from django.urls import path from.import views from.views import DRCreateView, update, DRUpdateView urlpatterns =[ path("", views.index, name="index"), path("addnew/", views.addnew, name='addnew'), path("add/", DRCreateView.as_view(), name='add'), path("success/", views.success, name='success'), path("update/<int:pk>", views.update, name='update'), path("updateview/<int:pk>", views.update, name='update'),]We need not change the myform.html script, as it renders the HTML script based on the respective model.
Visit the updateview/1 URL to render the form pre-filled with the object having primary key = 1. Try and change one or more values and update the table.
-
Opinionated Framework
Django has strong conventions and best practices, which can be restrictive for developers who prefer more flexibility in their architecture and design choices.
-
Limited Asynchronous Support
While Django has made strides in supporting asynchronous programming (especially with Django 3.1+), it is not as inherently designed for async tasks as some other frameworks like FastAPI or Node.js.
-
Performance Overhead
The abstraction layers and built-in features can introduce performance overhead, particularly in applications that require high speed or handle a large number of requests.
-
Insert Data
Django has its own Object Relation Model (ORM) that maps a Python class with a table in a relational database. The ORM mechanism helps in performing CRUD operations in object-oriented manner. In this chapter, we shall learn about different methods of inserting a new data.
By default, Django uses a SQLite database. A model in Django is a class inherited from the “django.db.models” class.
Let us use the following Dreamreal model in “models.py” file for learning how to insert data in the mapped table −
from django.db import models classDreamreal(models.Model): website = models.CharField(max_length=50) mail = models.CharField(max_length=50) name = models.CharField(max_length=50) phonenumber = models.IntegerField()classMeta:db_table ="dreamreal"</code></pre>After declaring a model, we need to perform the migrations −
python manage.py makemigrations python manage.py migrateInsert Object From Shell
Django has a useful feature with which you can invoke a Python shell inside the Django project’s environment. Use the shell command with the manage.py script −
python manage.py shellIn front of the Python prompt, import the Dreamreal model −
>>>from myapp.models import DreamrealWe can construct an object of this class and call its save() method so that the corresponding row is added in the table
>>> obj = Dreamreal(website="www.polo.com", mail="[email protected]", name="sorex", phonenumber="002376970")>>> obj.save()We can confirm this by opening the database in any SQLite viewer.
You can also use the create() method of the objects attribute of the model class to insert the record.
>>> obj = Dreamreal.objects.create(website="www.polo.com", mail="[email protected]", name="sorex", phonenumber="002376970")Perform Insert Operation by Calling a View Function
Let us now perform the insert operation by calling a View function. Define addnew() function in views.py file as follows −
from myapp.models import Dreamreal defaddnew(request): obj = Dreamreal(website="www.polo.com", mail="[email protected]", name="sorex", phonenumber="002376970") obj.save()return HttpResponse("<h2>Record Added Successfully")We need to register this View with the URLpatterns list.
from django.urls import path from.import views urlpatterns =[ path("", views.index, name="index"), path("addnew/", views.addnew, name='addnew')]Instead of using the hard-coded values as in the above example, we would like the data to be accepted from the user. For this purpose, create an HTML form in myform.html file.
<html><body><form action="../addnew/" method="post">{% csrf_token %} <p><label for="website">WebSite: </label><input id="website" type="text" name="website"></p><p><label for="mail">Email: </label><input id="mail" type="text" name="mail"></p><p><label for="name">Name: </label><input id="name" type="text" name="name"></p><p><label for="phonenumber">Phone Number: </label><input id="phonenumber" type="text" name="phonenumber"></p><input type="submit" value="OK"></form></body></html></code></pre>The HTML template file must be stored in a directory defined in the TEMPLATES setting −
TEMPLATES =[{'BACKEND':'django.template.backends.django.DjangoTemplates','DIRS':[BASE_DIR/'templates'],....,]Let us use the render() function to display the form template −
from django.shortcuts import render from myapp.models import Dreamreal defaddnew(request):if request.method =="POST":ws = request.POST['website'] mail = request.POST['mail'] nm = request.POST['name'] ph = request.POST['phonenumber'] obj = Dreamreal(website=ws, mail=mail, name=nm, phonenumber=ph) obj.save()return HttpResponse("<h2>Record Added Successfully</h2>")return render(request,"myform.html")</code></pre>Note that the form’s action attribute is also set to the same URL mapping the addnew() function. Hence, we need to check the request.method. If it’s GET method, the blank form is rendered. If it’s POST method, the form data is parsed and used for inserting a new record.

The Model Form
Django has a ModelForm class that automatically renders a HTML form with its structure matching with the attributes of a model class.
We define a DreamRealForm class in forms.py file under the app folder that uses the Dreamreal model as the basis.
from django import forms from.models import Dreamreal classDreamrealForm(forms.ModelForm):classMeta:model = Dreamreal fields ="__all__"</code></pre>An object of the model form is rendered on the HTML form. In case the request method is POST, the save() method of the ModelForm class automatically validates the form and saves a new record.
from.forms import DreamrealForm defaddnew(request):if request.method =='POST':
context={'form': DreamrealForm}return render(request,"myform.html", context)form = DreamrealForm(request.POST)if form.is_valid(): form.save()return HttpResponse("<h2>Book added successfully</h2>")
The CreateView Class
Django defines a collection of generic view classes. The CreateView class is specially designed for performing the INSERT query operation.
We define a subclass of CreateView class and set its template_name property to myform.html that we have already created.
Add the following code in views.py file −
from django.views.generic import CreateView classDRCreateView(CreateView): model = Dreamreal fields ="__all__" template_name ='myform.html' success_url ='../success/'On successful insertion, the browser is redirected to the success() view function.
defsuccess(request):return HttpResponse("<h2>Book added successfully</h2>")Both the above views must be included in the URL pattern list of urls.py file. The generic view classes are registered with their as_view() method.
from django.urls import path from.import views from.views import DRCreateView urlpatterns =[ path("", views.index, name="index"), path("addnew/", views.addnew, name='addnew'), path("add/", DRCreateView.as_view(), name='add'), path("success/", views.success, name='success'),]In this chapter, we learned the different ways to insert data in a Django model.
-
Monolithic Structure
Django’s “batteries-included” approach can lead to a monolithic architecture, making it challenging to break applications into microservices or smaller, more manageable components.
-
Steep Learning Curve
For beginners, the combination of Django’s conventions and its many built-in features can be overwhelming, leading to a steeper learning curve compared to simpler frameworks.
-
Models
A model is a class that represents table or collection in our DB, and where every attribute of the class is a field of the table or collection. Models are defined in the app/models.py (in our example: myapp/models.py)
Creating a Model
Following is a Dreamreal model created as an example −
from django.db import models class Dreamreal(models.Model): website = models.CharField(max_length = 50) mail = models.CharField(max_length = 50) name = models.CharField(max_length = 50) phonenumber = models.IntegerField() class Meta:db_table = "dreamreal"</code></pre>Every model inherits from django.db.models.Model.
Our class has 4 attributes (3 CharField and 1 Integer), those will be the table fields.
The Meta class with the db_table attribute lets us define the actual table or collection name. Django names the table or collection automatically: myapp_modelName. This class will let you force the name of the table to what you like.
After creating your model, you will need Django to generate the actual database −
$python manage.py syncdbManipulating Data (CRUD)
Let's create a "crudops" view to see how we can do CRUD operations on models. Our myapp/views.py will then look like −
myapp/views.py
from myapp.models import Dreamreal from django.http import HttpResponse def crudops(request): #Creating an entry dreamreal = Dreamreal(
) dreamreal.save() #Read ALL entries objects = Dreamreal.objects.all() res ='Printing all Dreamreal entries in the DB : <br>' for elt in objects:website = "www.polo.com", mail = "[email protected]", name = "sorex", phonenumber = "002376970"
#Read a specific entry: sorex = Dreamreal.objects.get(name = "sorex") res += 'Printing One entry <br>' res += sorex.name #Delete an entry res += '<br> Deleting an entry <br>' sorex.delete() #Update dreamreal = Dreamreal(res += elt.name+"<br>"
) dreamreal.save() res += 'Updating entry<br>' dreamreal = Dreamreal.objects.get(name = 'sorex') dreamreal.name = 'thierry' dreamreal.save() return HttpResponse(res)website = "www.polo.com", mail = "[email protected]", name = "sorex", phonenumber = "002376970"Other Data Manipulation
Let's explore other manipulations we can do on Models. Note that the CRUD operations were done on instances of our model, now we will be working directly with the class representing our model.
Let's create a 'datamanipulation' view in myapp/views.py
from myapp.models import Dreamreal from django.http import HttpResponse def datamanipulation(request): res = '' #Filtering data: qs = Dreamreal.objects.filter(name = "paul") res += "Found : %s results<br>"%len(qs) #Ordering results qs = Dreamreal.objects.order_by("name") for elt in qs:
return HttpResponse(res)res += elt.name + '<br>'Linking Models
Django ORM offers 3 ways to link models −
One of the first case we will see here is the one-to-many relationships. As you can see in the above example, Dreamreal company can have multiple online websites. Defining that relation is done by using django.db.models.ForeignKey −
myapp/models.py
from django.db import models class Dreamreal(models.Model): website = models.CharField(max_length = 50) mail = models.CharField(max_length = 50) name = models.CharField(max_length = 50) phonenumber = models.IntegerField() online = models.ForeignKey('Online', default = 1) class Meta:
class Online(models.Model):db_table = "dreamreal"
class Meta:domain = models.CharField(max_length = 30)db_table = "online"</code></pre>As you can see in our updated myapp/models.py, we added the online model and linked it to our Dreamreal model.
Let's check how all of this is working via manage.py shell −
First let’s create some companies (Dreamreal entries) for testing in our Django shell −
$python manage.py shell >>> from myapp.models import Dreamreal, Online >>> dr1 = Dreamreal() >>> dr1.website = 'company1.com' >>> dr1.name = 'company1' >>> dr1.mail = 'contact@company1' >>> dr1.phonenumber = '12345' >>> dr1.save() >>> dr2 = Dreamreal() >>> dr1.website = 'company2.com' >>> dr2.website = 'company2.com' >>> dr2.name = 'company2' >>> dr2.mail = 'contact@company2' >>> dr2.phonenumber = '56789' >>> dr2.save()Now some hosted domains −
>>> on1 = Online() >>> on1.company = dr1 >>> on1.domain = "site1.com" >>> on2 = Online() >>> on2.company = dr1 >>> on2.domain = "site2.com" >>> on3 = Online() >>> on3.domain = "site3.com" >>> dr2 = Dreamreal.objects.all()[2] >>> on3.company = dr2 >>> on1.save() >>> on2.save() >>> on3.save()Accessing attribute of the hosting company (Dreamreal entry) from an online domain is simple −
>>> on1.company.nameAnd if we want to know all the online domain hosted by a Company in Dreamreal we will use the code −
>>> dr1.online_set.all()To get a QuerySet, note that all manipulating method we have seen before (filter, all, exclude, order_by....)
You can also access the linked model attributes for filtering operations, let's say you want to get all online domains where the Dreamreal name contains 'company' −
>>> Online.objects.filter(company__name__contains = 'company'Note − That kind of query is just supported for SQL DB. It won’t work for non-relational DB where joins doesn’t exist and there are two '_'.
But that's not the only way to link models, you also have OneToOneField, a link that guarantees that the relation between two objects is unique. If we used the OneToOneField in our example above, that would mean for every Dreamreal entry only one Online entry is possible and in the other way to.
And the last one, the ManyToManyField for (n-n) relation between tables. Note, those are relevant for SQL based DB.
-
Update Objects
Once a model is registered with Django’s Admin app, we can easily perform CRUD operations on the model. In the previous chapter, we learned to register the Employee model. The homepage of admin site shows it under the MYAPP section −

Display The List of Objects
To display the list of objects, click on the name −

Add / Update / Delete an Object
To add/update/delete an object from the model, the current user must have been granted the required permission. Note that the superuser is equipped with all the permissions. Here, we assume that you have logged into the admin site with the superuser credentials.
If you want to change the contents of any of the objects displayed in the above figure, just click on the corresponding row in the list.
Let us open the object on the top of the list.

Let us update the values of Empname and Salary fields as shown. Click on the SAVE button, so that the corresponding row of the backend table is also updated.
The list of objects reappears with the changes made being reflected.

Note that the admin interface lets you to add/update/delete an object from the model, but it is not possible to change the structure of the model from the admin interface.
To add/modify/delete any of the attributes of any model, you need to edit the class definition and perform migrations for the change to be propagated to the database table mapped to the object.