0% found this document useful (0 votes)
4 views78 pages

CBLM Unit 07 Creating API Using Django REST Framework

The Competency Based Learning Material (CBLM) for 'Creating API Using Django REST Framework' is designed for Level-4 qualification under the National Skills Development Authority of Bangladesh. It provides structured training materials and activities aimed at developing skills in applying Django REST Framework concepts and creating CRUD projects. The document serves as a reference for educators and trainers to facilitate competency-based learning and assessment in web application development.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views78 pages

CBLM Unit 07 Creating API Using Django REST Framework

The Competency Based Learning Material (CBLM) for 'Creating API Using Django REST Framework' is designed for Level-4 qualification under the National Skills Development Authority of Bangladesh. It provides structured training materials and activities aimed at developing skills in applying Django REST Framework concepts and creating CRUD projects. The document serves as a reference for educators and trainers to facilitate competency-based learning and assessment in web application development.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Competency Based Learning Material (CBLM)

Web Application Development with Python

Level-4

Module: Creating API Using Django REST Framework

Code: CBLM- OU-ICT-WADP-07-L4-V1

National Skills Development Authority


Chief Advisor’s Office
Government of the People’s Republic of Bangladesh
Copyright

National Skills Development Authority


Chief Advisor's Office
Level6-11, Biniyog Bhaban,
E-6 / B, Agargaon, Sher-E-Bangla Nagar Dhaka-1207, Bangladesh.
Emailec@[Link]
[Link].
National Skills Portalhttp:\\[Link]

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)

This document is to be used as a key reference point by the competency-based learning


materials developers, teachers/trainers/assessors as a base on which to build instructional
activities.

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

Unit of Competency Create API Using Django REST Framework


Unit Code OU-ICT-WADP-07-L4-V1
Module Title Creating API Using Django REST Framework
This module covers the knowledge, skills and attitudes required to
create API using Django REST Framework
Module Descriptor
It includes the task of applying DRF concepts and creating CRUD
project
Nominal Hours 80 Hours
After completing the practice of the module, the trainees will be able to
perform the following jobs
Lerning Outcome 1. Apply DRF concepts
2. Create CRUD projec

Assessment Criteria

1. Serializers and views are applied


2. Class-based views are used
3. Mixins and generic class-based views are applied
4. Authentication, Token, Permission is implemented
5. Searching, filtering, and pagination are implemented
6. Project layout is created
7. Application setup
8. Database is set up
9. Blue print and views are applied
10. Project is made installable

1
Learning Outcome 1: Apply DRF concepts

1. Serializers and views are applied


2. Class-based views are used
Assessment Criteria
3. Mixins and generic class-based views are applied
4. Authentication, Token, Permission is implemented
5. Searching, filtering, and pagination are implemented
1. Real or simulated workplace
2. CBLM
3. Handouts
Conditions and 4. Laptop
Resources 5. Multimedia Projector
6. Paper, Pen, Pencil, Eraser
7. Internet facilities
8. White board and marker
9. Audio Video Device
1. DRF is installed
2. Serializers and views
3. Class-based views
Contents
4. Mixins and generic class-based views
5. Authentication, Token, Permission
6. Searching, filtering, and pagination
Activities/job/Task 1. Implement Serializers and Views in Django REST Framework
1. Discussion
2. Presentation
3. Demonstration
Training Methods 4. Guided Practice
5. Individual Practice
6. Project Work
7. Problem Solving
8. Brainstorming
Assessment methods may include but not limited to
1. Written Test
Assessment Methods
2. Demonstration
3. Oral Questioning
4. Portfolio

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.

Learning Activities Recourses/Special Instructions


1. Trainee will ask the instructor ` the 1. Instructor will provide the learning materials
learning materials ‘Apply DRF concepts’
2. Read Information sheet 1: Apply DRF
2. Read the Information sheet
concepts
and complete the Self Checks
3. Answer Self-check 1: Apply DRF concepts
& Check answer sheets on
4. Check your answer with Answer key 1:
“Apply DRF concepts”
Apply DRF concepts
3. Read the Job/Task Sheet and
5. Job Sheet-1: Implement Serializers and
Specification Sheet and
Views in Django REST Framework
perform job/Task

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:

1.1. Serializers and views are applied


1.2. Class-based views are used
1.3. Mixins and generic class-based views are applied
1.4. Authentication, Token, Permission is implemented
1.5. Searching, filtering, and pagination are implemented

1.1. Apply Serializers and views

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.

Why does the data need to be (de)serialized?

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:

You can easily adapt a ModelSerializer to your needs:

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.

1.2. Use Class-based views

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.

Usage in your URLconf


The most direct way to use generic views is to create them directly in your URLconf.
If you’re only changing a few attributes on a class-based view, you can pass them into
the as_view() method call itself:

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.

Subclassing generic views


The second, more powerful way to use generic views is to inherit from an existing
view and override attributes (such as the template_name) or methods (such
as get_context_data) in your subclass to provide new values or methods. Consider,
for example, a view that just displays one template, [Link]. Django has a generic
view to do this - TemplateView - so we can subclass it, and override the template
name:

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:

1.3. Mixins and generic 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.

Context and template responses

Two central mixins are provided that help in providing a consistent interface to working
with templates in class-based views.

TemplateResponseMixin

Every built in view which returns a TemplateResponse will call


the render_to_response() method that TemplateResponseMixin provides. Most of
the time this will be called for you (for instance, it is called by the get() method
implemented by both TemplateView and DetailView); similarly, it’s unlikely that
you’ll need to override it, although if you want your response to return something not
rendered via a Django template then you’ll want to do it. For an example of this, see
the JSONResponseMixin example.

render_to_response() itself calls get_template_names(), which by default will look


up template_name on the class-based view; two other mixins
(SingleObjectTemplateResponseMixin and MultipleObjectTemplateResponseMi
xin) override this to provide more flexible defaults when dealing with actual objects.

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.

Building up Django’s generic class-based views

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.

DetailView: working with a single Django object

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 get the object, DetailView relies on SingleObjectMixin, which provides


a get_object() method that figures out the object based on the URL of the request (it
looks for pk and slug keyword arguments as declared in the URLConf, and looks the
object up either from the model attribute on the view, or the queryset attribute if that’s
provided). SingleObjectMixin also overrides get_context_data(), which is used
across all Django’s built in class-based views to supply context data for template
renders.

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.)

ListView: working with many Django objects

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.

To get the objects, ListView uses MultipleObjectMixin, which provides


both get_queryset() and paginate_queryset(). Unlike with SingleObjectMixin,
there’s no need to key off parts of the URL to figure out the queryset to work with, so
the default uses the queryset or model attribute on the view class. A common reason
to override get_queryset() here would be to dynamically vary the objects, such as
depending on the current user or to exclude posts in the future for a blog.

MultipleObjectMixin also overrides get_context_data() to include appropriate


context variables for pagination (providing dummies if pagination is disabled). It relies
on object_list being passed in as a keyword argument, which ListView arranges for it.

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.)

Using Django’s class-based view mixins¶

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.

Using SingleObjectMixin with View¶

If we want to write a class-based view that responds only to POST, we’ll


subclass View and write a post() method in the subclass. However if we want our
processing to work on a particular object, identified from the URL, we’ll want the
functionality provided by SingleObjectMixin.

10
1.4. Implement Authentication, Token, Permission

Setting Up The REST API Project


So let’s start from the very beginning. Install Django and DRF:

pip install django


pip install djangorestframework
Create a new Django project:

[Link] startproject myapi .


Navigate to the myapi folder:
cd myapi
Start a new app. I will call my app core:
[Link] startapp core
Here is what your project structure should look like:

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',

# Local Apps (Your project's apps)


11
'[Link]',
]
Return to the project root (the folder where the [Link] script is), and
migrate the database:
python [Link] migrate
Let’s create our first API view just to test things out:

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]

But usually I prefer to use HTTPie, which is a pretty awesome Python


command line tool:
http [Link]
13
Now let’s protect this API endpoint so we can implement the token
authentication:

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

def get(self, request):


content = {'message': 'Hello, World!'}
return Response(content)
Try again to access the API endpoint:

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.

Implementing the Token Authentication

We need to add two pieces of information in our [Link] module. First


include rest_framework.authtoken to your INSTALLED_APPS and include
the TokenAuthentication to REST_FRAMEWORK :

myapi/[Link]
INSTALLED_APPS = [
# Django Apps
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',

# Third-Party Apps
'rest_framework',
'rest_framework.authtoken', # <-- Here

# Local Apps (Your project's apps)


'[Link]',
]

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

Now we need a user account. Let’s just create one using


the [Link] command line utility:
python [Link] createsuperuser --username vitor --email
vitor@[Link]
The easiest way to generate a token, just for testing purpose, is using the
command line utility again:

python [Link] drf_create_token vitor

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.

So finally, let’s use our token!

http [Link] 'Authorization: Token


9054f7aa9305e012b3c2300408c3dfdf390fcddf'

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'

Or if it was a Python requests call:


import requests

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);
}
}

User Requesting a Token


The DRF provide an endpoint for the users to request an authentication
token using their username and password.

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.

Let’s try again:


http post [Link] username=vitor
password=123

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

1.5. Implement Searching, filtering, and pagination

When developing APIs for modern web applications, it’s essential to


implement features like pagination, search, and filtering to improve user
experience and optimize performance. In this blog post, we’ll break down how
to implement a GET API using [Link], Express, and MongoDB that
handles pagination, search (filtering), and sorting for a test series.

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.

If no values for page or limit are provided, the default values of


page 1 and limit 10 are used.
• We calculate the startIndex and endIndex based on these values, which
helps in slicing the data for pagination.
3. Search and Filtering
In most cases, users will want to search or filter items based on specific fields,
such as the name, category, or sub-category of the test series. For this, we
construct a filter object based on the query parameter searchTerm.

23
The filter is built using the MongoDB $regex operator to perform case-
insensitive partial text matching. Here’s how we set it up:

• The $or operator allows us to search across multiple fields.


• The $regex operator performs a text search based on the
provided searchTerm, with the i option for case-insensitivity.
4. Sorting
Sorting allows users to view data in a specific order, such as alphabetically or
by date. Sorting is handled by the sortBy query parameter, which consists of
two parts: the field to sort by and the sort order (ascending or descending).

• 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.

5. Fetching the Data


Once the pagination, filtering, and sorting configurations are set, we fetch the
data from MongoDB using Mongoose’s .find() method. We apply
the filter and sort conditions and then slice the data for pagination.
24
• We first retrieve all matching documents from the database using
the .find(filter) method.
• Then, we apply the sorting using .sort(sort).
• Finally, we slice the results using the slice(startIndex, endIndex) method
to implement pagination.

6. Sending the Response


After retrieving the data, we send the response to the client in JSON format.
The response includes the paginated test series, total number of
pages, current page, and total number of items.

• totalPages: The total number of pages, calculated by dividing the total


number of items by the page limit.
• currentPage: The current page number.
• totalItems: The total number of matching items in the database.

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

1. What is the primary function of a serializer in Django REST framework?


Answer:
o A. To handle user authentication requests
o B. To define the representation of data records for REST services
o C. To manage database connections and queries
o D. To render HTML templates for web applications

2. Which of the following statements is most accurate about serializers in Django


REST framework?
Answer:
o A. They are always complex classes requiring extensive coding.
o B. They can inherit from base classes like [Link] for
simpler implementations.
o C. They are not necessary for building REST services with Django REST
framework.
o D. They are responsible for handling incoming HTTP requests.

3. What is the advantage of using class-based views in Django REST framework


compared to regular Django views decorated with @api_view?
Answer:
o A. Class-based views offer no significant advantages.
o B. Class-based views provide a more readable and organized approach for
complex REST services.
o C. Class-based views are mandatory for using serializers in Django REST
framework.
o D. Class-based views are not compatible with generic views like
ListCreateAPIView.

4. What is the role of mixins in Django REST framework?


Answer:
o A. Mixins are used to define custom authentication schemes for REST
services.
o B. Mixins encapsulate common logic for REST services, promoting code
reuse.)
o C. Mixins are a mandatory component for using generic class-based views.
o D. Mixins are primarily used for handling database transactions.

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

1. What is the primary function of a serializer in Django REST framework?


o A. To handle user authentication requests
o B. To define the representation of data records for REST services
(Correct)
o C. To manage database connections and queries
o D. To render HTML templates for web applications

2. Which of the following statements is most accurate about serializers in Django


REST framework?
o A. They are always complex classes requiring extensive coding.
o B. They can inherit from base classes like [Link] for
simpler implementations. (Correct)
o C. They are not necessary for building REST services with Django REST
framework.
o D. They are responsible for handling incoming HTTP requests.

3. What is the advantage of using class-based views in Django REST framework


compared to regular Django views decorated with @api_view?
o A. Class-based views offer no significant advantages.
o B. Class-based views provide a more readable and organized approach
for complex REST services. (Correct)
o C. Class-based views are mandatory for using serializers in Django REST
framework.
o D. Class-based views are not compatible with generic views like
ListCreateAPIView.

4. What is the role of mixins in Django REST framework?


o A. Mixins are used to define custom authentication schemes for REST
services.
o B. Mixins encapsulate common logic for REST services, promoting code
reuse. (Correct)
o C. Mixins are a mandatory component for using generic class-based views.
o D. Mixins are primarily used for handling database transactions.

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

Working Procedure / Steps

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

• Programming Language: Python 3.7 or later


• Framework: Django 3.2 or later
• Django REST framework: Additional library for building REST APIs

Tools and Equipment

• Computer: A computer with sufficient processing power, RAM, and storage.


• Terminal: A command-line interface for executing commands.
• Text Editor/IDE: Visual Studio Code, PyCharm, Sublime Text (or any preferred
code editor).

30
Learning Outcome 2: Create CRUD project

1. Project layout is created


2. Application setup
Assessment Criteria
3. Database is set up
4. Blue print and views are applied
5. Project is made installable
1. Real or simulated workplace
2. CBLM
3. Handouts
Conditions and 4. Laptop
Resources 5. Multimedia Projector
6. Paper, Pen, Pencil, Eraser
7. Internet facilities
8. White board and marker
9. Audio Video Device
1. CRUD project
Contents
2. API Testing
Activities/job/Task 2. Create a CRUD Django Application
1. Discussion
2. Presentation
3. Demonstration
Training Methods 4. Guided Practice
5. Individual Practice
6. Project Work
7. Problem Solving
8. Brainstorming
Assessment methods may include but not limited to
1. Written Test
Assessment Methods
2. Demonstration
3. Oral Questioning
4. Portfolio

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:

2.1. Project layout is created


2.2. Application setup
2.3. Database is set up
2.4. Blue print and views are applied
2.5. Project is made installable

2.1. Create Project layout

Project Organization:

Your Django project will be organized into several key directories, each serving a
specific purpose:

▪ your_project_name/ (Main Project Directory):

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.

2.2. Application setup


Django is a powerful Python web framework that simplifies web development by
providing a clean and pragmatic design. One of the most common tasks in web
development is creating CRUD (Create, Read, Update, Delete) functionality for your
application. In this article, we'll explore how to create a Django CRUD project using
function-based views.

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.

Setting Up Your Django Project

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."

Application Registration: you need to configure in your [Link] file


Make sure your app (myapp) is included in the INSTALLED_APPS list:
INSTALLED_APPS = [
# ...
'myapp',
]

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]:

from [Link] import models

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:

python [Link] makemigrations


python [Link] migrate

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'}),
}

Creating Function-Based Views

Function-based views are a simple and straightforward way to handle CRUD


operations in Django. In this example, we'll create views for creating, reading,
updating, and deleting orders.
37
Create a Order (Create View) In crudapp/[Link], define a view function for creating
new order:

from [Link] import redirect, render


from .forms import OrderForm
from .models import Orders

# Create your views here.


def orderFormView(request):
form = OrderForm()
if [Link] == 'POST':
form = OrderForm([Link])
if form.is_valid():
[Link]()
return redirect('show_url')
template_name = 'crudapp/[Link]'
context = {'form': form}
return render(request, template_name, context)

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.

▪ Update a Order (Update View) To update a order, create a view


in crudapp/[Link]:

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]:

def deleteView(request, f_oid):


obj = [Link](oid=f_oid)
if [Link] == 'POST':
[Link]()
return redirect('show_url')
template_name = 'crudapp/[Link]'
context = {'obj': obj}
return render(request, template_name, context)

In this view, we confirm the order deletion with a confirmation page.

Creating Templates

39
Now, create HTML templates for the views in the crudproject/templates directory.
You'll need templates for the following views:

[Link]: for creating base html file with navbar.

Similarly, create HTML templates for the views in the crudproject/templates/crudapp


directory. You'll need templates for the following views:
[Link]: For the create and update forms. [Link]: For listing all orders.
[Link]: For confirming order deletion.

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 %}

<script src="[Link] integrity="sha384-


KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG
5KkN" crossorigin="anonymous"></script>
<script src="[Link]
integrity="sha384-
ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q
" crossorigin="anonymous"></script>
<script src="[Link]
integrity="sha384-
JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl
" crossorigin="anonymous"></script>
</body>
</html>

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>&nbsp;&nbsp;
<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 %}

Add Bootstrap Crispy forms for styling form and navbar

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'),
]

Testing Your CRUD Project

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'
}
}

2.4. Blueprint and views

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

# import the standard Django Model


# from built-in library
from [Link] import models

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/")

# renames the instances of the model


# with their title name
def __str__(self):
return [Link]

,
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

Provide URL patterns to map with views function.


// [Link]
from [Link] import admin
from [Link] import path
from employee import views
urlpatterns = [
path('admin/', [Link]),
path('emp', [Link]),
path('show',[Link]),
path('edit/<int:id>', [Link]),
path('update/<int:id>', [Link]),
path('delete/<int:id>', [Link]),
]

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>

Static Files Handling

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'
]

Run the command to migrate the migrations.

$ python3 [Link] migrate

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.

See list of tables created after migrate command.

Run Server

To run server use the following command.


1. $ python3 [Link] runserver
55
Access to the Browser

Access the application by entering localhost:8000/show, it will show all the available
employee records.

Initially, there is no record. So, it shows no record message.

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.

After deleting, we left with the following records.

Well, we have successfully created a CRUD application using Django.

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:

from setuptools import setup, find_packages

setup(
name='your-app-name',
version='0.1.0',
packages=find_packages(),
include_package_data=True,
install_requires=[
'django',
# Any other dependencies
],
)

un python [Link] sdist bdist_wheel to create source and wheel distributions.

Install Your App in Another Project

▪ 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

Register Your App in the Main Project (myproject/[Link])

▪ In myproject/[Link], add your app to the INSTALLED_APPS list:


Python
INSTALLED_APPS = [
# ... other apps
'crudapp',

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/

2. What command is used to create a new Django project?

Answer:

• a) django-createproject project_name
• b) django-initproject project_name
• c) django-admin startproject project_name
• d) django startproject project_name

3. In which file are database models defined in a Django application?

Answer:

• a) [Link]
• b) [Link]
• c) [Link]
• d) [Link]

4. What does the Django ORM (Object Relational Mapper) do?

Answer:

• a) Defines the URL patterns for a Django application.


• b) Provides a way to interact with a database using Python objects.
• c) Handles form validation in Django views.
• d) Manages the development server for a Django project.

5. What purpose does a template serve in a Django application?

Answer:

• a) Defines the logic for handling user requests.


• b) Holds the HTML structure and content displayed to the user.
• c) Specifies the database schema for a Django application.
• d) Defines the forms used for user input in a Django application.

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: c) [Link] Answer

2. What command is used to create a new Django project?

Answer: c) django-admin startproject project_name

3. In which file are database models defined in a Django application?

Answer: b) [Link]

4. What does the Django ORM (Object Relational Mapper) do?

Answer: b) Provides a way to interact with a database using Python objects.

5. What purpose does a template serve in a Django application?

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

Working Procedure / Steps

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:

4.1. Choose a Database:


Decide on the database you want to use. Django supports various databases like MySQL,
PostgreSQL, SQLite (default).
4.2. Configure Database Settings:
In your project's [Link] file, define the database connection details in the DATABASES
dictionary

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

• Programming Language: Python 3.7 or later


• Framework: Django 3.2 or later
• Database: Choose a compatible database backend (e.g., MySQL, PostgreSQL,
SQLite)

Tools and Equipment

• Computer: A computer with sufficient processing power, RAM, and storage.


• Terminal: A command-line interface for executing commands.
• Text Editor/IDE: Visual Studio Code, PyCharm, Sublime Text (or any preferred
code editor).

65
Reference

1. [Link]
2. [Link]

66
Review of Competency
Below is yourself assessment rating for module “Creating API Using Django REST
Framework”

Assessment of performance Criteria Yes No


Serializers and views are applied
Class-based views are used
Mixins and generic class-based views are applied
Authentication, Token, Permission is implemented
Searching, filtering, and pagination are implemented
Project layout is created
Application setup
Database is set up
Blue print and views are applied
Project is made installable

I now feel ready to undertake my formal competency assessment.

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.

SL Name and Address Designation Contact Number


No.
1 Khan Mohammad Writer Cell: 01714087897
Mahmud Hasan Email: kmmhasan@[Link]
2 A K M Mashuqur Editor Cell: 01676323576
Rahman Mazumder Email :
[Link]@[Link]
3 Khan Mohammad Co-Ordinator Cell: 01714087897
Mahmud Hasan Email: kmmhasan@[Link]
4 Md. Saif Uddin Reviewer Cell:01723004419
Email:
[Link]@[Link]

68

You might also like