CBLM Unit 07 Creating API Using Django REST Framework
CBLM Unit 07 Creating API Using Django REST Framework
Level-4
This Competency Based Learning Materials (CBLM) on “Creating API Using Django REST
Framework” under the Web Application Development with Python , Level-4 qualification
is developed based on the national competency standard approved by National Skills
Development Authority (NSDA)
National Skills Development Authority (NSDA) is the owner of this document. Other
interested parties must obtain written permission from NSDA for reproduction of information
in any manner, in whole or in part, of this Competency Standard, in English or other language.
It serves as the document for providing training consistent with the requirements of industry in
order to meet the qualification of individuals who graduated through the established standard
via competency-based assessment for a relevant job.
This document has been developed by NSDA in association with industry representatives,
academia, related specialist, trainer, and related employee. Public and private institutions may
use the information contained in this CBLM for activities benefitting Bangladesh.
i
ii
Approved by the Authority ………. meeting held on .................
iii
iv
How to use this Competency Based Learning Material (CBLM)
The module contains training materials and activities for you to complete. These activities may
be completed as part of structured classroom activities or you may be required you to work at
your own pace. These activities will ask you to complete associated learning and practice
activities in order to gain knowledge and skills you need to achieve the learning outcomes.
1. Review the Learning Activity page to understand the sequence of learning activities
you will undergo. This page will serve as your road map towards the achievement of
competence.
2. Read the Information sheet s. This will give you an understanding of the jobs or tasks
you are going to learn how to do. Once you have finished reading the Information
sheet s complete the questions in the Self-Check.
3. Self-Checks are found after each Information sheet . Self-Checks are designed to
help you know how you are progressing. If you are unable to answer the questions in
the Self-Check you will need to re-read the relevant Information sheet . Once you
have completed all the questions check your answers by reading the relevant Answer
Keys found at the end of this module.
4. Next move on to the Job Sheets. Job Sheets provide detailed information about how
to do the job you are being trained in. Some Job Sheets will also have a series of
Activity Sheets. These sheets have been designed to introduce you to the job step by
step. This is where you will apply the new knowledge you gained by reading the
Information sheet s. This is your opportunity to practise the job. You may need to
practise the job or activity several times before you become competent.
5. Specification sheets, specifying the details of the job to be performed will be provided
where appropriate.
6. A review of competency is provided on the last page to help remind if all the required
assessment criteria have been met. This record is for your own information and
guidance and is not an official record of competency
When working though this Module always be aware of your safety and the safety of others in
the training room. Should you require assistance or clarification please consult your trainer or
facilitator.
When you have satisfactorily completed all the Jobs and/or Activities outlined in this
module, an assessment event will be scheduled to assess if you have achieved competency
in the specified learning outcomes. You will then be ready to move onto the next Unit of
Competency or Module
v
vi
Table of Contents
Copyright ................................................................................................................................... i
How to use this Competency Based Learning Material (CBLM)........................................ v
Module Content ........................................................................................................................ 1
Learning Outcome 1: Apply DRF concepts........................................................................... 2
Learning Experience 1: Apply DRF concepts .................................................................................................... 3
Information sheet 1: Apply DRF concepts ......................................................................................................... 4
1.1. Apply Serializers and views..................................................................................... 4
1.2. Use Class-based views ............................................................................................. 6
1.3. Mixins and generic class-based views ..................................................................... 7
1.4. Implement Authentication, Token, Permission ..................................................... 11
1.5. Implement Searching, filtering, and pagination ..................................................... 22
Self-Check Sheet 1: Apply DRF concepts ......................................................................................................... 27
Answer Key 1: Apply DRF concepts ................................................................................................................. 28
Job Sheet-1: Implement Serializers and Views in Django REST Framework .............................................. 29
Specification Sheet 1: Implement Serializers and Views in Django REST Framework ............................... 30
Learning Outcome 2: Create CRUD project....................................................................... 31
Learning Experience 2: Create CRUD project ................................................................................................ 32
Information sheet 2: Create CRUD project ..................................................................................................... 33
2.1. Create Project layout .............................................................................................. 33
2.2. Application setup ................................................................................................... 34
2.3. Setup Database ....................................................................................................... 45
2.4. Blueprint and views ............................................................................................... 45
2.5. Project installable ................................................................................................... 61
Self-Check Sheet Create CRUD project ........................................................................................................... 62
Answer Key Create CRUD project .................................................................................................................. 63
Job Sheet-2: Create a CRUD Django Application ........................................................................................... 64
Specification Sheet 2: Create a CRUD Django Application ............................................................................ 65
Reference ................................................................................................................................ 66
Review of Competency .......................................................................................................... 67
Development of CBLM .......................................................................................................... 68
iii
iv
Module Content
Assessment Criteria
1
Learning Outcome 1: Apply DRF concepts
2
Learning Experience 1: Apply DRF concepts
In order to achieve the objectives stated in this learning guide, you must perform the
learning steps below. Beside each step are the resources or special instructions you will
use to accomplish the corresponding activity.
3
Information sheet 1: Apply DRF concepts
Learning Objective:
After completion of this Information sheet , the learners will be able to explain, define
and interpret the following contents:
Serializers are used to convert Django QuerySets and model instances to and from
JSON. Also, before deserializing the data, for incoming payloads, serializers validate
the shape of the data.
Django QuerySets and model instances are Django-specific and, as such, not universal.
In other words, the data structure needs to be converted into a simplified structure
before it can be communicated over a RESTful API.
Serializers are one of the main building blocks of the Django REST framework used to
define the representation of data records, which are generally based on Django models.
As described in the previous section on Introduction to REST services options for
Django, Python records can have ambiguous data representations (e.g. a record with
a datetime value can be represented as DD/MM/YYYY, DD-MM-YYYY or MM-
YYYY) and a serializer removes any uncertainty about how to represent a record.
Example illustrates a Django REST framework serializer using one
its serializers package. To specify how incoming and outgoing data gets serialized and
deserialized, you create a [SomeResource]Serializer class. So, if you have
a Task model, you'd create a TaskSerializer class.
4
For example:
Similarly to how Django forms are created, when the serialization is closely coupled to
the model, you can extend from ModelSerializer:
Here, we-
1. Explicitly defined the fields the serializer has access to via the fields attribute
2. Set the completed field to read-only
3. Added additional data -- short_description
5
DRF also allows you to create a hypertext-driven API:
While these are just basic examples, they should give you a good idea of how serializers
work and why they're necessary.
A view is a callable which takes a request and returns a response. This can be more
than just a function, and Django provides an example of some classes which can be
used as views. These allow you to structure your views and reuse code by harnessing
inheritance and mixins. There are also some generic views for tasks which we’ll get to
later, but you may want to design your own structure of reusable views which suits
your use case. For full details, see the class-based views reference documentation.
Basic examples
Django provides base view classes which will suit a wide range of applications. All
views inherit from the View class, which handles linking the view into the URLs,
HTTP method dispatching and other common features. RedirectView provides a
HTTP redirect, and TemplateView extends the base class to make it also render a
template.
6
Any arguments passed to as_view() will override attributes set on the class. In this
example, we set template_name on the TemplateView. A similar overriding pattern
can be used for the url attribute on RedirectView.
Then we need to add this new view into our URLconf. TemplateView is a class, not a
function, so we point the URL to the as_view() class method instead, which provides
a function-like entry to class-based views:
Django’s built-in class-based views provide a lot of functionality, but some of it you
may want to use separately. For instance, you may want to write a view that renders a
template to make the HTTP response, but you can’t use TemplateView; perhaps you
need to render a template only on POST, with GET doing something else entirely.
While you could use TemplateResponse directly, this will likely result in duplicate
code.
7
For this reason, Django also provides a number of mixins that provide more discrete
functionality. Template rendering, for instance, is encapsulated in
the TemplateResponseMixin. The Django reference documentation contains full
documentation of all the mixins.
Two central mixins are provided that help in providing a consistent interface to working
with templates in class-based views.
TemplateResponseMixin
ContextMixin
Every built in view which needs context data, such as for rendering a template
(including TemplateResponseMixin above), should call get_context_data() passing
any data they want to ensure is in there as keyword
arguments. get_context_data() returns a dictionary; in ContextMixin it returns its
keyword arguments, but it is common to override this to add more members to the
dictionary. You can also use the extra_context attribute.
Let’s look at how two of Django’s generic class-based views are built out of mixins
providing discrete functionality. We’ll consider DetailView, which renders a “detail”
view of an object, and ListView, which will render a list of objects, typically from a
queryset, and optionally paginate them. This will introduce us to four mixins which
between them provide useful functionality when working with either a single Django
object, or multiple objects.
8
There are also mixins involved in the generic edit views (FormView, and the model-
specific views CreateView, UpdateView and DeleteView), and in the date-based
generic views. These are covered in the mixin reference documentation.
To show the detail of an object, we basically need to do two things: we need to look up
the object and then we need to make a TemplateResponse with a suitable template,
and that object as context.
To then make
a TemplateResponse, DetailView uses SingleObjectTemplateResponseMixin,
which extends TemplateResponseMixin, overriding get_template_names() as
discussed above. It actually provides a fairly sophisticated set of options, but the main
one that most people are going to use is <app_label>/<model_name>_detail.html.
The _detail part can be changed by setting template_name_suffix on a subclass to
something else. (For instance, the generic edit views use _form for create and update
views, and _confirm_delete for delete views.)
Lists of objects follow roughly the same pattern: we need a (possibly paginated) list of
objects, typically a QuerySet, and then we need to make a TemplateResponse with a
suitable template using that list of objects.
9
To make a TemplateResponse, ListView then
uses MultipleObjectTemplateResponseMixin; as
with SingleObjectTemplateResponseMixin above, this
overrides get_template_names() to provide a range of options, with the most
commonly-used being <app_label>/<model_name>_list.html, with the _list part
again being taken from the template_name_suffix attribute. (The date based generic
views use suffixes such as _archive, _archive_year and so on to use different
templates for the various specialized date-based list views.)
Now we’ve seen how Django’s generic class-based views use the provided mixins,
let’s look at other ways we can combine them. We’re still going to be combining them
with either built-in class-based views, or other generic class-based views, but there are
a range of rarer problems you can solve than are provided for by Django out of the
box.
10
1.4. Implement Authentication, Token, Permission
myapi/
|-- core/
| |-- migrations/
| |-- __init__.py
| |-- [Link]
| |-- [Link]
| |-- [Link]
| |-- [Link]
| +-- [Link]
|-- __init__.py
|-- [Link]
|-- [Link]
+-- [Link]
[Link]
Add the core app (you created) and the rest_framework app (you installed)
to the INSTALLED_APPS , inside the [Link] module:
myapi/[Link]
INSTALLED_APPS = [
# Django Apps
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
# Third-Party Apps
'rest_framework',
myapi/core/[Link]
from rest_framework.views import APIView
from rest_framework.response import Response
class HelloView(APIView):
def get(self, request):
content = {'message': 'Hello, World!'}
return Response(content)
Now register a path in the [Link] module:
myapi/[Link]
from [Link] import path
from [Link] import views
urlpatterns = [
path('hello/', [Link].as_view(), name='hello'),
]
So now we have an API with just one endpoint /hello/ that we can
perform GET requests. We can use the browser to consume this endpoint, just
by accessing the URL [Link] :
12
We can also ask to receive the response as plain JSON data by passing
the format parameter in the querystring
like [Link] :
Both methods are fine to try out a DRF API, but sometimes a command line
tool is more handy as we can play more easily with the requests headers.
You can use cURL, which is widely available on all major Linux/macOS
distributions:
curl [Link]
myapi/core/[Link]
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated # <-- Here
class HelloView(APIView):
permission_classes = (IsAuthenticated,) # <-- And
here
http [Link]
14
And now we get an HTTP 403 Forbidden error. Now let’s implement the token
authentication so we can access this endpoint.
myapi/[Link]
INSTALLED_APPS = [
# Django Apps
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
# Third-Party Apps
'rest_framework',
'rest_framework.authtoken', # <-- Here
15
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.[Link]', # <--
And here
],
}
Migrate the database to create the table that will store the authentication tokens:
python [Link] migrate
16
This piece of information, the random
string 9054f7aa9305e012b3c2300408c3dfdf390fcddf is what we are going to
use next to authenticate.
But now that we have the TokenAuthentication in place, let’s try to make
another request to our /hello/ endpoint:
http [Link]
Notice how our API is now providing some extra information to the client on
the required authentication method.
17
And that’s pretty much it. For now on, on all subsequent request you should
include the header Authorization: Token
9054f7aa9305e012b3c2300408c3dfdf390fcddf .
The formatting looks weird and usually it is a point of confusion on how to set
this header. It will depend on the client and how to set the HTTP request
header.
For example, if we were using cURL, the command would be something like
this:
curl [Link] -H 'Authorization: Token
9054f7aa9305e012b3c2300408c3dfdf390fcddf'
url = '[Link]
headers = {'Authorization': 'Token
9054f7aa9305e012b3c2300408c3dfdf390fcddf'}
r = [Link](url, headers=headers)
Or if we were using Angular, you could implement an HttpInterceptor and
set a header:
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from
'@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
const user = [Link]([Link]('user'));
if (user && [Link]) {
request = [Link]({
setHeaders: {
Authorization: `Token ${[Link]}`
}
});
}
return [Link](request);
}
}
18
Include the following route to the [Link] module:
myapi/[Link]
from [Link] import path
from rest_framework.[Link] import obtain_auth_token # <--
Here
from [Link] import views
urlpatterns = [
path('hello/', [Link].as_view(), name='hello'),
path('api-token-auth/', obtain_auth_token,
name='api_token_auth'), # <-- And here
]
So now we have a brand new API endpoint, which is /api-token-auth/ . Let’s first
inspect it:
http [Link]
It doesn’t handle GET requests. Basically it’s just a view to receive a POST
request with username and password.
19
The response body is the token associated with this particular user. After
this point you store this token and apply it to the future requests.
Then, again, the way you are going to make the POST request to the API
depends on the language/framework you are using.
If this was an Angular client, you could store the token in the localStorage , if
this was a Desktop CLI application you could store in a text file in the user’s
home directory in a dot file.
a. Generating Tokens
To automatically generate a token for each user upon creation, you can
use Django’s signals in combination with Django REST Framework’s
(DRF) TokenAuthentication. Specifically, Django’s post_save signal
can trigger token creation whenever a new user instance is saved
1. Import Necessary Modules
In your Django app, create a [Link] file or add these imports in your
[Link] if you don't want a separate file.
20
2. Define the Signal
Using the @receiver decorator, define a signal function that listens for
the post_save event on the User model. This function will automatically
create a token for the user after they are saved to the database
sender-settings.AUTH_USER_MODEL:
This ensures that the signal is connected to the user model.
instance: Refers to the user instance being saved.
created: Indicates if the user was created (as opposed to updated
3. Connect the Signal in Your App
To make sure the signal is registered, import your [Link] in the app's
[Link] file
21
Then, set this custom app config in your [Link]
4. Run Migrations
Ensure that the token model is properly set up by running migrations if
you haven't already
5. Test the Setup
After creating a new user, you should see a token automatically
generated for that user in the database
22
1. Setting Up the API Endpoint
We’re using an Express router to define an API route for fetching test series.
Below is the basic structure of the route handler for the /api/testSeries endpoint.
2. Pagination
Pagination is used to break large datasets into smaller chunks, making it easier
to load, display, and navigate through large collections of data. In the API,
pagination is controlled by two query parameters:
• page: The current page number, starting from 1.
• limit: The number of items to be displayed on each page.
23
The filter is built using the MongoDB $regex operator to perform case-
insensitive partial text matching. Here’s how we set it up:
• We split the sortBy query parameter using : to separate the field and the sort
order.
• order === 'desc' ? -1 : 1 ensures that the sorting order is descending (-1) or
ascending (1), based on the provided query parameter.
25
7. Handling Errors
To handle any potential errors that may arise during the execution of the API
(such as database connectivity issues), we wrap the entire code inside a try-
catch block. If an error occurs, we send a 500 status code and an error message.
26
Self-Check Sheet 1: Apply DRF concepts
5. What is the benefit of using viewsets and routers in Django REST framework?
Answer:
o A. Viewsets and routers simplify the creation of individual views for each
CRUD operation.
o B. Viewsets and routers provide a more concise way to define views for
complex REST services.
o C. Viewsets and routers are necessary for using authentication with Django
REST framework.
o D. Viewsets and routers offer no advantages and are optional for building
REST services.
27
Answer Key 1: Apply DRF concepts
5. What is the benefit of using viewsets and routers in Django REST framework?
o A. Viewsets and routers simplify the creation of individual views for each
CRUD operation.
o B. Viewsets and routers provide a more concise way to define views for
complex REST services. (Correct)
o C. Viewsets and routers are necessary for using authentication with Django
REST framework.
o D. Viewsets and routers offer no advantages and are optional for building
REST services.
28
Job Sheet-1: Implement Serializers and Views in Django REST
Framework
UoC Cover
OU-ICT-WADP-02- L7-V1: Creating API Using Django REST Framework
1. Create Serializers:
o Serializers define the representation of data records in a Django REST
framework.
o They are used to convert Django model instances into other formats
like JSON or XML.
2. Define Serializer Class:
o Create a Python class that inherits from [Link] or a
more specific
o Use fields from [Link] to define the data transformation for
each model field.
3. Create Views:
o Views handle incoming requests, process data, and return responses.
o Django REST framework offers several view options:
▪ Regular Django View with @api_view decorator:
▪ Use this for basic REST services.
▪ Class-based Views:
▪ More concise and reusable than regular views.
▪ Generic Class-based Views:
▪ Provide pre-built functionalities for common CRUD
operations.
▪ View Sets:
▪ Group multiple related views together.
29
Specification Sheet 1: Implement Serializers and Views in Django
REST Framework
Technical Requirements
30
Learning Outcome 2: Create CRUD project
31
Learning Experience 2: Create CRUD project
In order to achieve the objectives stated in this learning guide, you must perform the
learning steps below. Beside each step are the resources or special instructions you will
use to accomplish the corresponding activity.
Learning Activities Recourses/Special Instructions
1. Trainee will ask the instructor about 1. Instructor will provide the learning materials
the learning materials ‘Create CRUD project’
2. Read Information sheet 2: Create CRUD
2. Read the Information sheet
project
and complete the Self Checks
3. Answer Self-check 2: Create CRUD project
& Check answer sheets on
4. Check your answer with Answer key 2:
“Create CRUD project”
Create CRUD project
3. Read the Job/Task Sheet and
5. Job Sheet-2: Create a CRUD Django
Specification Sheet and
Application
perform job/Task
32
Information sheet 2: Create CRUD project
Learning Objective:
After completion of this Information sheet , the learners will be able to explain, define
and interpret the following contents:
Project Organization:
Your Django project will be organized into several key directories, each serving a
specific purpose:
o [Link]: This script acts as the command center for your project.
Use it to run various tasks like starting the development server,
creating apps, managing database migrations, and more.
o your_app_name/ (App Directory): - Replace your_app_name with the
actual name of your application (e.g., blog, products). This directory
houses all the code specific to your CRUD functionality.
▪ [Link] (Optional): This file allows you to register your data
models with the Django admin interface, providing a user-
friendly way to manage data through a web interface.
▪ [Link] (Optional): This file (optional) serves as a
configuration file for your app. It typically specifies the app
name and any dependencies it might have on other Django
apps.
▪ migrations/: This directory stores database migration files.
These files track changes made to your data models and
facilitate updating your database schema when the models
evolve.
▪ [Link]: This core file defines your data models. Here,
you'll create model classes representing the data you intend to
33
manage (e.g., Post model for a blog, Product model for an e-
commerce application).
▪ [Link] (Optional): This file is an excellent practice to include
unit tests for your app's functionalities. Writing tests ensures
your code works as expected and helps prevent regressions
during future development.
▪ [Link]: This file defines the functions (views) responsible
for handling user requests and generating responses. These
responses can be HTML pages, JSON data, or other formats
depending on your application's needs.
▪ [Link]: This file defines the URL patterns for your app. It
maps incoming URLs to specific views within your app,
ensuring the correct view handles each user request.
▪ templates/ (Optional): This directory (optional) holds HTML
templates used for rendering dynamic content in your views.
▪ your_app_name/ (App-Specific Template
Directory): This subdirectory within templates/ contains
the HTML template files specific to your app's views
(e.g., [Link] for displaying a list of items, [Link] for
showing details of a single item, [Link] for creating a
new item, [Link] for editing an existing item).
o [Link]: This critical file holds essential configuration settings for
your entire Django project. It defines details like the database
connection, installed apps (including your your_app_name app), secret
keys for security purposes, and other project-wide settings.
o [Link]: This file defines the main project-level URL patterns. It
typically includes patterns that delegate incoming requests to specific
app URL configurations (e.g., your_app_name.urls).
o [Link]: This file serves as the entry point for the Web Server
Gateway Interface (WSGI) server. It provides a way for web servers
like Apache or Nginx to interact with your Django application.
34
Prerequisites
Before we dive into building our CRUD project, make sure you have the following
prerequisites in place:
1. Python and Django: Ensure you have Python installed on your system. You
can install Django using pip:
pip install django
2. Database: Decide on the database you want to use. By default, Django uses
SQLite, but you can configure it to use other databases like PostgreSQL,
MySQL, or Oracle.
3. Text Editor or IDE: Choose a code editor or integrated development
environment (IDE) of your preference. Popular choices include Visual Studio
Code, PyCharm, or Sublime Text.
Let's start by creating a new Django project and a new app within that project. Open
your terminal and run the following commands:
django-admin startproject crudproject
cd crudproject
python [Link] startapp crudapp
We've created a new project named "crudproject" and an app named "crudapp."
Defining Models
In Django, models are Python classes that define the structure of your database tables.
For our CRUD project, let's assume we want to manage a list of orders. Create a
model for the orders in crudapp/[Link]:
35
# Create your models here.
class Orders([Link]):
oid = [Link](primary_key=True)
fname = [Link](max_length=20)
lname = [Link](max_length=20)
price = [Link]()
mail = [Link]()
addr = [Link](max_length=50)
Now, it's time to create the database tables for our models. Run the following
commands to create the migrations and apply them:
Creating Forms
We mentioned using a form for creating and updating orders. You can define the form
in crudapp/[Link]:
from django import forms
36
from .models import Orders
class OrderForm([Link]):
class Meta:
model = Orders
fields = '__all__'
labels = {
'oid': 'Order ID',
'fname' : 'First Name',
'lname' : 'Last Name.' ,
'price' : 'Price' ,
'mail' : 'Email ID',
'addr' : 'Address' ,
}
widgets ={
'oid' : [Link](attrs={'placeholder': 'eg. 101'}),
'fname' : [Link](attrs={'placeholder': 'eg. Prosenjeet'}),
'lname' : [Link](attrs={'placeholder': 'eg. Shil'}),
'price' : [Link](attrs={'placeholder': 'eg. 10000'}),
'mail' : [Link](attrs={'placeholder': 'eg. abc@[Link]'}),
'addr' : [Link](attrs={'placeholder': 'eg. IN'}),
}
In this view, we handle both GET and POST requests. If it's a GET request, we render
a form for creating a new order. If it's a POST request, we validate the form data and
save the new order if it's valid.
▪ Read Orders (List View) Now, let's create a view to display a list of all books
in crudapp/[Link]:
def showView(request):
obj = [Link]()
template_name = 'crudapp/[Link]'
context = {'obj': obj}
return render(request, template_name, context)
This view retrieves all orders from the database and renders them using a template.
38
def updateView(request, f_oid):
obj = [Link](oid=f_oid)
form = OrderForm(instance=obj)
if [Link] == 'POST':
form = OrderForm([Link], instance=obj)
if form.is_valid():
[Link]()
return redirect('show_url')
template_name = 'crudapp/[Link]'
context = {'form': form}
return render(request, template_name, context)
▪ Delete a Order (Delete View) Finally, let's create a view to delete a order
in crudapp/[Link]:
Creating Templates
39
Now, create HTML templates for the views in the crudproject/templates directory.
You'll need templates for the following views:
Below, are the templates for base file and the three views we discussed earlier:
crudproject/templates/[Link]
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
{% block title %}
<title>Layout Page</title>
{% endblock %}
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel="stylesheet"
href="[Link]
integrity="sha384-
Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6J
Xm" crossorigin="anonymous">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">CRUD APP</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-
target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-
expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
40
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="{% url 'order_url' %}">Add Orders<span
class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'show_url' %}">Show Orders</a>
</li>
</ul>
</div>
</nav>
{% block content %}
{% endblock %}
crudproject/templates/crudapp/[Link]
{% extends '[Link]' %}
{% load crispy_forms_tags %}
{% block title %}
<title>Add Page</title>
{% endblock %}
41
{% block content %}
<center><h1>Order Form</h1></center>
<div class="container">
<form method="post" class="jumbotron">
{% csrf_token %}
{{form|crispy}}
<input type="submit" value="Place Order" class="btn btn-success">
</form>
</div>
{% endblock %}
crudproject/templates/crudapp/[Link]
{% extends '[Link]' %}
{% block title %}
<title>Show Page</title>
{% endblock %}
{% block content %}
<center><h1>Show Orders</h1></center>
<table class="table">
<thead>
<tr>
<th scope="col">Order ID</th>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">Price</th>
<th scope="col">Email ID</th>
<th scope="col">Address</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
{% for i in obj %}
<tr>
<td>{{[Link]}}</td>
<td>{{[Link]}}</td>
42
<td>{{[Link]}}</td>
<td>{{[Link]}}</td>
<td>{{[Link]}}</td>
<td>{{[Link]}}</td>
<td>
<button class="btn btn-warning"><a href="{% url 'update_url' [Link]
%}">Update</a></button>
<button class="btn btn-danger"><a href="{% url 'delete_url' [Link]
%}">Delete</a></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
crudproject/templates/crudapp/[Link]
{% extends '[Link]' %}
{% block title %}
<title>Confirmation Page</title>
{% endblock %}
{% block content %}
<div class="container">
<form class="jumbotron" method="post">
{% csrf_token %}
<h2>Are you sure you want to delete this data? </h2>
<input type="submit" value="YES" class="btn btn-danger">
<button class="btn btn-success"><a href="{% url 'show_url'
%}">No</a></button>
</form>
</div>
{% endblock %}
43
INSTALLED_APPS = [
# ...
'crispy_forms',
'crispy_bootstrap5',
]
CRISPY_TEMPLATE_PACK = 'bootstrap5'
Wiring Up URLs
Finally, configure the URLs for your views. In your project's crudproject/[Link] file,
include the URLs for the crudapp app:
from [Link] import admin
from [Link] import path, include
urlpatterns = [
path('admin/', [Link]),
path('', include('[Link]'))
]
Then, in your app's crudpp/[Link] file, define the URLs for your views:
from [Link] import path
from . import views
urlpatterns = [
path('ofv/', [Link], name='order_url'),
path('sv/', [Link], name='show_url'),
path('up/<int:f_oid>', [Link], name= 'update_url'),
path('del/<int:f_oid>', [Link], name= 'delete_url'),
]
With everything set up, you can start your Django development server:
python [Link] runserver
44
2.3. Setup Database
Create a database djangodb in mysql, and configure into the [Link] file of
django project. See the example.
// [Link]
DATABASES = {
'default': {
'ENGINE': '[Link]',
'NAME': 'djangodb',
'USER':'root',
'PASSWORD':'mysql',
'HOST':'localhost',
'PORT':'3306'
}
}
Create a Model
Put the following code into [Link] file.
// [Link]
from [Link] import models
class Employee([Link]):
eid = [Link](max_length=20)
ename = [Link](max_length=100)
eemail = [Link]()
econtact = [Link](max_length=15)
class Meta:
db_table = "employee"
Create a ModelForm
45
# declare a new model with a name "GeeksModel"
class GeeksModel([Link]):
# fields of the model
title = [Link](max_length = 200)
description = [Link]()
last_modified = [Link](auto_now_add = True)
img = [Link](upload_to = "images/")
,
To create a form directly for this model, dive into geeks/[Link] and Enter following
code,
// [Link]
from django import forms
from [Link] import Employee
class EmployeeForm([Link]):
class Meta:
model = Employee
fields = "__all__"
46
Create View Functions
// [Link]
from [Link] import render, redirect
from [Link] import EmployeeForm
from [Link] import Employee
# Create your views here.
def emp(request):
if [Link] == "POST":
form = EmployeeForm([Link])
if form.is_valid():
try:
[Link]()
return redirect('/show')
except:
pass
else:
form = EmployeeForm()
return render(request,'[Link]',{'form':form})
def show(request):
employees = [Link]()
return render(request,"[Link]",{'employees':employees})
def edit(request, id):
employee = [Link](id=id)
return render(request,'[Link]', {'employee':employee})
def update(request, id):
employee = [Link](id=id)
form = EmployeeForm([Link], instance = employee)
if form.is_valid():
[Link]()
return redirect("/show")
return render(request, '[Link]', {'employee': employee})
def destroy(request, id):
employee = [Link](id=id)
[Link]()
return redirect("/show")
47
Provide Routing
Organize Templates
Create a templates folder inside the employee app and create three (index, edit,
show) html files inside the directory. The code for each is given below.
// [Link]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Index</title>
{% load staticfiles %}
<link rel="stylesheet" href="{% static 'css/[Link]' %}"/>
</head>
<body>
<form method="POST" class="post-form" action="/emp">
{% csrf_token %}
<div class="container">
<br>
48
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<h3>Enter Details</h3>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Employee Id:</label>
<div class="col-sm-4">
{{ [Link] }}
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Employee Name:</label>
<div class="col-sm-4">
{{ [Link] }}
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Employee Email:</label>
<div class="col-sm-4">
{{ [Link] }}
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Employee Contact:</label>
<div class="col-sm-4">
{{ [Link] }}
</div>
</div>
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
49
</form>
</body>
</html>
// [Link]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Employee Records</title>
{% load staticfiles %}
<link rel="stylesheet" href="{% static 'css/[Link]' %}"/>
</head>
<body>
<table class="table table-striped table-bordered table-sm">
<thead class="thead-dark">
<tr>
<th>Employee ID</th>
<th>Employee Name</th>
<th>Employee Email</th>
<th>Employee Contact</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for employee in employees %}
<tr>
<td>{{ [Link] }}</td>
<td>{{ [Link] }}</td>
<td>{{ [Link] }}</td>
<td>{{ [Link] }}</td>
<td>
<a href="/edit/{{ [Link] }}"><span class="glyphicon glyphicon-
pencil" >Edit</span></a>
<a href="/delete/{{ [Link] }}">Delete</a>
</td>
50
</tr>
{% endfor %}
</tbody>
</table>
<br>
<br>
<center><a href="/emp" class="btn btn-
primary">Add New Record</a></center>
</body>
</html>
// [Link]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Index</title>
{% load staticfiles %}
<link rel="stylesheet" href="{% static 'css/[Link]' %}"/>
</head>
<body>
<form method="POST" class="post-form" action="/update/{{[Link]}}">
{% csrf_token %}
<div class="container">
<br>
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<h3>Update Details</h3>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Employee Id:</label>
<div class="col-sm-4">
<input type="text" name="eid" id="id_eid" required maxlength="20" value
="{{ [Link] }}"/>
51
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Employee Name:</label>
<div class="col-sm-4">
<input type="text" name="ename" id="id_ename" required maxlength="10
0" value="{{ [Link] }}" />
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Employee Email:</label>
<div class="col-sm-4">
<input type="email" name="eemail" id="id_eemail" required maxlength="
254" value="{{ [Link] }}" />
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Employee Contact:</label>
<div class="col-sm-4">
<input type="text" name="econtact" id="id_econtact" required maxlength=
"15" value="{{ [Link] }}" />
</div>
</div>
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<button type="submit" class="btn btn-success">Update</button>
</div>
</div>
</div>
</form>
</body>
</html>
52
Create a folder static/css inside the employee app and put a css inside it. Download
the css file here Click Here.
Project Structure
53
Create Migrations
Create migrations for the created model employee, use the following command.
1. $ python3 [Link] makemigrations
After migrations, execute one more command to reflect the migration into the
database. But before it, mention name of app (employee) in INSTALLED_APPS of
[Link] file.
// [Link]
INSTALLED_APPS = [
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'employee'
]
54
Now, our application has successfully connected and created tables in database. It
creates 10 default tables for handling project (session, authentication etc) and one
table of our model that we created.
Run Server
Access the application by entering localhost:8000/show, it will show all the available
employee records.
Adding Record
Click on the Add New Record button and fill the details. See the example.
56
Filling the details.
57
Submit the record and see, after submitting it shows the saved record.
This section also allows, update and delete records from the actions column.
After saving couple of records, now we have following records.
Update Record
Lets update the record of Mohan by clicking on edit button. It will display record of
Mohan in edit mode.
58
Lets, suppose I update mohan to mohan kumar then click on the update button. It
updates the record immediately. See the example.
Click on update button and it redirects to the following page. See name is updated.
59
Same like, we can delete records too, by clicking the delete link.
Delete Record
Suppose, I want to delete Sohan, it can be done easily by clicking the delete button.
See the example.
60
2.5. Project installable
You can create a distributable package for your app using setuptools:
• Install setuptools (pip install setuptools).
• Create a [Link] file in the project root:
setup(
name='your-app-name',
version='0.1.0',
packages=find_packages(),
include_package_data=True,
install_requires=[
'django',
# Any other dependencies
],
)
▪ Navigate to the project where you want to use your CRUD app.
▪ Install the app from the distribution file (if you packaged it) or from the Git
repository using pip:
Bash
pip install path/to/[Link] # For distribution file
pip install git+[Link] # From Git
61
Self-Check Sheet Create CRUD project
1. Which of the following is NOT a part of the core directory structure of a Django
project?
Answer:
• a) your_project_name/
• b) [Link]
• c) [Link]
• d) your_app_name/
Answer:
• a) django-createproject project_name
• b) django-initproject project_name
• c) django-admin startproject project_name
• d) django startproject project_name
Answer:
• a) [Link]
• b) [Link]
• c) [Link]
• d) [Link]
Answer:
Answer:
62
Answer Key Create CRUD project
1. Which of the following is NOT a part of the core directory structure of a Django
project?
Answer: b) [Link]
Answer: b) Holds the HTML structure and content displayed to the user.
63
Job Sheet-2: Create a CRUD Django Application
UoC Cover
OU-ICT-WADP-02- L7-V1: Creating API Using Django REST Framework
1. Project Setup:
1.1. Create a Django Project: Open your terminal and run the following command:
1.2. Create a Django App: Navigate to your project directory
2. Application Configuration:
2.1. Register Your App: In your project's [Link] file, ensure your app (crudapp) is
included in the INSTALLED_APPS list
3. Model Definition:
Define your data model in crudapp/[Link]. This model represents the data you want to
manage (e.g., Order, Product, Employee).
4. Database Setup:
5. Forms: Forms are useful for creating user-friendly interfaces for adding and editing data.
Define them in crudapp/[Link].
6. Views: Views handle user requests and generate responses. Define them in
crudapp/[Link].
64
Specification Sheet 2: Create a CRUD Django Application
Technical Requirements
65
Reference
1. [Link]
2. [Link]
66
Review of Competency
Below is yourself assessment rating for module “Creating API Using Django REST
Framework”
Signed:
Date:
67
Development of CBLM
The Competency based Learning Material (CBLM) of ‘Creating API Using Django REST
Framework’ (Occupation: Web Application Development with Python , Level-4) for National
Skills Certificate is developed by NSDA with the assistance of SAMAHAR Consultants [Link]
the month of June, 2024 under the contract number of package SD-9C dated 15th January 2024.
68