Django Rest Framework (DRF) is a sub-framework of the Django framework. Django is one of the most popular Python frameworks used in web development. DRF is used to create RESTful APIs that integrate the backend with the frontend. Compared to third-party APIs, DRF gives developers full control over their APIs.
-
Visual Studio Code (VS Code): Download and install it from the browser.
-
Python: Install the latest version of Python. After installation, check the installed version using:
python --version
-
Project Setup:
- Create a new folder on the desktop and name it
drf_project. - Open that folder in VS Code.
- Create a new folder on the desktop and name it
-
Setting Up Virtual Environment & Installing Dependencies:
- Create a
requirements.txtfile and add the following dependencies:django>=4.0.0 djangorestframework pyyaml requests django-cors-headers - Open a new terminal in VS Code and navigate to the project directory.
- Run the following commands:
python --version # Ensure Python is installed python -m venv myenv # Create a virtual environment pip freeze # List the latest versions of installed packages pip install -r requirements.txt # Install required dependencies
- Create a
Django is used for web development. Install Django and create a new Django project using:
pip install django
django-admin --version
django-admin startproject projectname # Create Django project
cd projectname # Navigate to project folder
python manage.py runserver # Run the server to check project setupIn this project, two apps (api and products) are created.
- Apps are sub-projects within a Django project, allowing modular development.
- Create an app using:
python manage.py startapp appname
- Register the created app in
settings.py:INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'appname', # Add your app here ]
- Create
urls.pyinside the app folder and link it in the mainurls.pyfile of the project.
Modify INSTALLED_APPS to include DRF:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'appname', # Add your app here
]- Create a separate folder named
py_client. - Inside it, create a file
basic.py. - Define the function in
views.pyof theproductsapp. - Add the URL in
urls.pyof the app. - In
basic.py, define an endpoint variable and set the API URL. - Click on the URL to check if the API is working.
To fetch data from the database, use request methods like GET and POST.
To edit or insert values into the model, use:
python manage.py shell- Import the model and create an object.
- The data is returned in a dictionary (key-value pairs).
Convert API views to DRF views by importing:
from rest_framework.response import Response- This response class returns data in JSON format.
Serializers in DRF work similarly to Django forms.
- Create a new file
serializers.pyinside the app. - Import serializers using:
from rest_framework import serializers
- Define the model in
models.py. - Register the model in
admin.py:admin.site.register(appname)
- Run migrations:
python manage.py makemigrations python manage.py migrate
- Define a serializer class in
serializers.pyand link it to the model.
- Define a view method in
views.pyusing DRF serializers. - Use decorators (
POST,GET) for handling requests. - Data from
POSTrequests is automatically saved in the model.
- Register the API views in
urls.pyof the app.
POST– Ingest new data.GET– Retrieve all saved data.
RetrieveAPIViewfetches a single record using its primary key (ID).
RetrieveAPIViewfetches a single record based on ID.- It handles lookups, serialization, and 404 errors.
- Queryset and filtering can be customized.
- Add the API URL in
urls.pyof the app. - Create a
details.pyfile insidepy_client. - Add the app URL as an endpoint to fetch details of models/products.
In Django Rest Framework (DRF), generics.CreateAPIView is used to create new records via a POST request. It automatically handles serialization and validation.
CreateAPIViewhandlesPOSTrequests to create new records.- It automatically manages serialization, validation, and saving data.
- You can extend it with custom validation, authentication, and permissions if needed.
ListAPIView is used to retrieve a list of objects, while ListCreateAPIView allows both retrieving and creating objects within a single view.
- This allows only
GETrequests to list all products.
- This allows both
GET(fetch all products) andPOST(add a new product).
Add the following URL patterns inside urls.py:
urlpatterns = [
path('products/', ProductListAPIView.as_view(), name='product-list'),
path('products/create/', ProductListCreateAPIView.as_view(), name='product-list-create'),
]DRF allows using Function-Based Views (FBVs) with the @api_view decorator to handle Create, Retrieve, and List operations.
| Operation | HTTP Method | Description |
|---|---|---|
create_product |
POST |
Create a new product. |
retrieve_product |
GET |
Retrieve a single product by ID. |
list_products |
GET |
List all products. |
- Create view for
POST(create product). - Create view for
GET(retrieve a single product). - Create view for
GET(list all products).
Define the URLs for these views in urls.py.
In DRF, UpdateAPIView is used to update an existing object, while DestroyAPIView is used to delete an object. These generic views automatically handle serialization, validation, and HTTP methods.
Define a built-in view in views.py using ProductUpdateAPIView.
PUT: Updates all fields of a product.PATCH: Updates only the provided fields.
Define a built-in view in views.py using ProductDestroyAPIView.
urlpatterns = [
path('product/update/<int:pk>/', ProductUpdateAPIView.as_view(), name='update-product'),
path('product/delete/<int:pk>/', ProductDestroyAPIView.as_view(), name='delete-product'),
]Mixins provide reusable behaviors that can be combined with Django's generic API views for flexible and modular APIs.
Define a built-in view in views.py using ProductListCreateView.
Define a built-in view in views.py using ProductRetrieveUpdateDestroyView.
urlpatterns = [
path('products/', ProductListCreateView.as_view(), name='product-list-create'),
path('products/<int:pk>/', ProductRetrieveUpdateDestroyView.as_view(), name='product-retrieve-update-destroy'),
]- Reusability: Avoid code duplication by mixing functionalities (
list,create,update,delete). - Flexibility: Unlike
ListAPIVieworRetrieveAPIView,GenericAPIViewlets you define multiple methods in one class. - Customization: You can add custom logic inside each method.
Django Rest Framework (DRF) provides Session Authentication to authenticate users based on Django’s built-in authentication system. It also provides permissions to restrict access based on user roles.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication', # Enable Session Authentication
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated', # Require authentication by default
]
}Note: SessionAuthentication requires users to be logged in via Django’s login system (/admin/ or a custom login view).
Define a built-in view in views.py and import permissions.
Django provides a powerful authentication and permission system that allows assigning permissions to individual users or groups. Model-level permissions control who can create, read, update, or delete a model’s data.
To manage permissions via Django Admin, follow these steps:
- First, create a superuser:
python manage.py createsuperuser
- Log into Django Admin at http://127.0.0.1:8000/admin/
- Navigate to Users & Groups:
- Assign specific permissions to individual users.
- Create a new group (e.g., Product Managers) and assign model permissions.
You can also define permissions via code by creating a separate permissions.py file inside your app.
Django Rest Framework (DRF) provides built-in permission classes, but sometimes you need more control over access. You can create custom permission classes to define specific rules.
A custom permission class must inherit from BasePermission and override the has_permission() or has_object_permission() methods.
- Write the logic for the permissions you need.
- Define the view for permissions in views.py of your app.
- Sometimes, you may want to restrict access based on user groups.
- Example: Allow only users in the
"Product Managers"group.
- If you want to control access per object, override
has_object_permission(). - Example: Allow users to edit only their own profiles.
- Combine multiple permissions using
AND,OR, andNOTlogic. - Example: Only allow authenticated users AND admins.
- Allow only certain HTTP methods.
- Example: Restrict access to GET requests only.
Django Rest Framework (DRF) provides Token Authentication to secure APIs. Users receive a token after logging in, which they use in API requests instead of sending their username and password each time.
Run the following commands:
pip install djangorestframework
pip install djangorestframework-authtokenAdd the following to your INSTALLED_APPS:
INSTALLED_APPS = [
'rest_framework',
'rest_framework.authtoken', # Enables Token Authentication
'yourappname', # Replace with your actual app name
]Run the migration command to create the token table in the database:
python manage.py migrateUpdate settings.py to enable Token Authentication:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication', # Enable Token Auth
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated', # Require authentication by default
]
}Each user needs a token to access the API. You can generate tokens manually or automatically when a user registers.
Run the following command in the Django shell:
python manage.py shellThen, create a token for an existing user (replace your_user with an actual user instance):
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
user = User.objects.get(username="your_user") # Replace with actual username
token, created = Token.objects.get_or_create(user=user)
print(token.key)- Create a new file named signals.py inside your app folder.
- Register
signals.pyin apps.py of your app.
Now, a token is automatically generated when a new user is created.
Define an endpoint for users to obtain authentication tokens:
from django.urls import path
from rest_framework.authtoken.views import obtain_auth_token
urlpatterns = [
path('api/token/', obtain_auth_token, name='api_token_auth'),
]Now, users can send their credentials to /api/token/ and receive a token in response.
Django provides a powerful user authentication and permission system, allowing you to assign permissions to individual users or groups. Model-level permissions control who can create, read, update, or delete a model’s data.
To allow permissions for the user through a group, first, create a superuser using the following command:
python manage.py createsuperuser- Log into Django Admin at http://127.0.0.1:8000/admin/.
- Navigate to Users & Groups:
- Assign specific permissions to individual users.
- Create a new group (e.g., Product Managers) and assign model permissions.
You can also assign permissions programmatically by writing logic separately in a new file named permissions.py within your app.
Django Rest Framework (DRF) provides built-in permission classes, but sometimes you need more control over who can access what in your API. You can create custom permission classes to define specific rules.
A custom permission class must inherit from BasePermission and override the has_permission() or has_object_permission() methods.
- Write the logic for the permissions you want to add.
- Define the view for permissions in
views.pyof the app.
- Sometimes, you may want to restrict access based on user groups.
- Example: Allow only users in the "Product Managers" group.
- If you want to control access per object, override
has_object_permission(). - Example: Allow users to edit only their own profiles.
- You can combine multiple permissions using AND, OR, and NOT logic.
- Example: Allow only Authenticated Users AND Admins.
- You can allow only certain HTTP methods.
- Example: Allow only
GETrequests.
Django Rest Framework (DRF) provides Token Authentication as a way to secure APIs. With this, users receive a token after logging in, which they use in API requests instead of sending a username and password each time.
pip install djangorestframework
pip install djangorestframework-authtokenINSTALLED_APPS = [
'rest_framework',
'rest_framework.authtoken', # Enables Token Authentication
'yourappname', # Replace with your app name
]python manage.py migrateREST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication', # Enable Token Auth
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated', # Require authentication by default
]
}Each user needs a token to access the API. You can generate tokens manually or automatically when a user registers.
Run the following command in Django Shell:
python manage.py shellThen, write the code to create a token (replace actual_user with your user instance).
- Create a new file named
signals.pyin the app folder. - Register this
signals.pyinapps.pyof the app/product folder. - Now, a token is automatically generated when a new user is created.
- Add the URL configuration in
urls.py.
Django Rest Framework (DRF) provides default settings that control authentication, permissions, pagination, throttling, and more. You can configure these settings in your settings.py file under the REST_FRAMEWORK dictionary.
Throttling limits the number of requests a client can make to an API within a specified period to prevent abuse and ensure fair usage.
AnonRateThrottle– Limits requests for unauthenticated users.UserRateThrottle– Limits requests for authenticated users.ScopedRateThrottle– Limits requests based on a specific scope.- Custom Throttling – You can create your own throttling logic by extending
BaseThrottle.
Controls the output format.
DRF provides mixins that allow you to easily manage API permissions. By combining mixins with generic views, we can create reusable permission logic.
Using mixins allows us to:
- Reuse permission logic across multiple views.
- Keep views clean and maintainable.
- Customize access control for different user roles.
- Create a new file
mixins.pyin the app folder. - Import the permissions from
permissions.pyand extend them with mixins.
| Mixin | Purpose |
|---|---|
IsAdminUserMixin |
Only admin users can access |
IsAuthenticatedMixin |
Only logged-in users can access |
IsOwnerMixin |
Only object owners can edit/delete |
ReadOnlyMixin |
Everyone can read; only authenticated users can edit |
In DRF, ViewSets and Routers simplify API development by automatically handling CRUD operations and URL routing.
A ViewSet is a higher-level abstraction that combines multiple views into a single class. Instead of writing separate views for list, retrieve, create, update, and delete, you can use a ViewSet to handle them all.
A Router automatically generates URLs for ViewSets, dynamically mapping HTTP methods to ViewSet actions.
- Define a Model → Create a model in
models.py. - Create a Serializer → Define
serializers.py. - Define a ViewSet → Implement
views.py. - Use a Router for URLs → Modify
urls.py.
👉 Now, you don’t need to manually define URLs for each API action!
- URLs: Define API routes in
urls.pyusingpath()andre_path(). - Reverse: Use
reverse()to generate URLs dynamically. - Serializers: Convert Django models into JSON using ModelSerializer.
ModelSerializer provides built-in create() and update() methods to handle object creation and updates.
create(validated_data)→ Creates and saves a new instance.update(instance, validated_data)→ Updates an existing instance.
- Override
create()for custom logic (e.g., modifying field values). - Override
update()to enforce additional validation.
You can perform custom validation in serializers using:
- Field-level validation (
validate_<field_name>()) - Object-level validation (
validate()) - Extra
kwargsin the Meta class - Validators argument in fields
Step # 26: Request User Data and Customize View Queryset
In Django, you can request user-specific data and customize the queryset based on the logged-in user. This is useful when you want to display only relevant data to each user, such as their own posts, orders, or profile information.
Django provides the request.user object, which represents the currently logged-in user. You can use it in your views to filter querysets.
Example: Fetching User-Specific Data
If you are using Django’s generic class-based views (CBVs), you can override get_queryset to return user-specific data.
Example: Restricting Data in ListView
If you're working with Django Rest Framework (DRF), you can customize the queryset in a ViewSet.
Example: Filtering API Results by User
If you want to show only relevant data in the Django Admin panel, override get_queryset in the admin model.
Step # 27: Related Fields and Foreign Key Serializer
When dealing with ForeignKey and related fields in Django Rest Framework (DRF), you can serialize relationships in different ways, such as using PrimaryKeyRelatedField, StringRelatedField, Nested Serializers, or HyperlinkedRelatedField.
- Using HyperlinkedRelatedField (Hyperlinks Instead of IDs)
This field provides a URL instead of an ID for related objects.
- The best approach depends on the use case and API requirements.
- Use nested serializers when you need full details but be mindful of performance.
- Use
PrimaryKeyRelatedFieldfor simple foreign key references to keep responses lightweight.
Step # 28: Pagination
- For adding Pagination, go to
settings.py. - Add
DEFAULT_PAGINATION_CLASSin theREST_FRAMEWORKsection. - We can customize the limit of items on each page with the help of pagination classes. There are different types of pagination classes.
Uses limit and offset query parameters to control the number of records.
Query parameters:
limit: Number of items per page (e.g.,?limit=10).offset: Number of items to skip (e.g.,?offset=20).
Query parameter: cursor.
If pagination is not required, you can set it to None in the settings.
Step # 29: A Django-Based Search for Our Product API
You can build a Django-based search API for your product database using Django Rest Framework (DRF). Here's a step-by-step guide.
python manage.py startapp searchAdd 'search' to INSTALLED_APPS.
INSTALLED_APPS = [
# other apps...
'rest_framework',
'products',
]Using the following import statements:
from rest_framework import generics
from .models import Product
from .serializers import ProductSerializerfrom django.urls import path
from .views import ProductSearchView
urlpatterns = [
path('search/', ProductSearchView.as_view(), name='product-search'),
]python manage.py runserverStep # 30: Building Your Search Engine on Algolia
- Algolia provides a third-party API that we integrate into our code.
- Login to Algolia and select Django framework.
- For integration, first install the Algolia package in the Django project.
- Add attributes in
settings.pyand add the prefix of the app/models. - Create the
index.pyfile in each app that we want to connect with Algolia. - Then use the following import statement to use the Algolia package.
from algoliasearch_django import AlgoliaIndexStep # 31: Algolia Search Client for Django
- Create a new file named
client.pyin thesearchapp and implement the code logic using classes/methods. - Create a view in
views.py.
Step # 32: Unified Design of Serializers and Indices
- Arrange the view of fields, meaning display only the fields we want to show to the user and hide the fields that should not be shown.
Step # 33: Json web token Authentication with simplejwt
-
Go to Python JWT Client for DRF web site copy the client side code and create new file in
py_clientnamed asjwt.pyand paste all the code in it. -
Add the drf jwt in settings.py in installed apps.
-
To use jwt install the package in drf named as;
djangorestframework-simplejwt- To view Token response go to the (jwt.io) and paste your taken.
- The sequences matters when authenticated the drf token in
settings.py.
Step # 34: Login via JavaScript Client
-
Create new folder named as
js-clientadd two filesindex.htmlto create login form andjs.clientfor form functionality using javascript to post form data in database (db). -
To run JavaScript Server;
python -m http.server 8111(port)Step # 35: Handle Request Blocked by CORS via django-cors-headers
- First of all install package django-cors-headers for handle cors request in javascript. Use command;
pip install -r requirements.txt- Include corsheaders in Installed_apps in
settings.pyby writting;
'corsheaders',- To allow cors headers in js need to add middleware in
settings.pyabove the commonMiddleware in Middleware section. Just like that.
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', # here add middleware
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]- To access the cors header from different locations/apis add the urls in allowed hosts in
settings.py.
Step # 36: Using JWT With JS Client
- Add few additions in
client.js.