0% found this document useful (0 votes)
30 views

REST API Using Django Rest Framework

Master Django REST Framework with this comprehensive guide. Perfect for students and professionals, it covers everything from basics to advanced techniques. Learn serializers, views, authentication, permissions, and more with clear, practical explanations. Understand not just how, but when and why to use each feature. Elevate your API development skills and create robust, efficient RESTful APIs with ease.(from a developer curious about not just how but also why, when and where to use everything)

Uploaded by

msedits91
Copyright
© © All Rights Reserved
0% found this document useful (0 votes)
30 views

REST API Using Django Rest Framework

Master Django REST Framework with this comprehensive guide. Perfect for students and professionals, it covers everything from basics to advanced techniques. Learn serializers, views, authentication, permissions, and more with clear, practical explanations. Understand not just how, but when and why to use each feature. Elevate your API development skills and create robust, efficient RESTful APIs with ease.(from a developer curious about not just how but also why, when and where to use everything)

Uploaded by

msedits91
Copyright
© © All Rights Reserved
You are on page 1/ 52

API

API (Application Programming Interface) is a way to manage data across different devices.
This note focuses on APIs built using Django Rest Framework.

Key points:

1. Data in APIs is often passed in JSON format.


2. Serializers are used to convert data to JSON (serializing) and back (deserializing).
3. Process:
○ Create a Django model
○ Migrate the model
○ Create a serializer.py file

Serializer creation:

1. Import the model and Django Rest Framework serializers


2. Create a class that inherits from serializers.ModelSerializer
3. Set up a Meta class inside the serializer class
4. Specify the model and fields to serialize

Example:

\
SerializerMethodField and Validate Methods in Django Rest Framework

1. SerializerMethodField

SerializerMethodField is a special field in Django Rest Framework serializers. It's used when
you want to include data in your serialized output that doesn't directly correspond to a model
field.

Key points:

● It's read-only by default


● It gets its value by calling a method on the serializer class
● The method name should be 'get_<field_name>'

Example:

In this example, 'full_name' is a SerializerMethodField. It calls the 'get_full_name' method to


generate its value.

SerializerMethodField is like a custom calculator in our API waiter's toolkit. It can create new
information based on existing data. For example, it can combine a person's first and last
name to create a full name, even if 'full_name' isn't a field in our database.
2. Validate Methods

Validate methods in serializers are used to add custom validation logic to your fields or the
entire object.

There are two types of validate methods:

a. Field-level validation:

● Method name should be 'validate_<field_name>'


● It's called for each field individually

Example:

b. Object-level validation:

● Method name should be 'validate'


● It's called after all field-level validations
● It receives a dictionary of field values

Example:
Validate methods are like security guards for our data. They check if the data is correct
before allowing it into our system.

● Field-level validate methods check individual pieces of information. For example,


making sure a person's age isn't a negative number.
● Object-level validate methods look at multiple pieces of information together. For
example, making sure a person's birth year isn't in the future compared to the current
year.

1. Basic Concept

Object-level validation allows you to validate multiple fields together or perform complex
validation that depends on more than one field. This is done using the validate() method
in your serializer class.

Example:
2. Advanced Usage

a. Accessing context: The validate() method can access the serializer's context, which
can be useful for validations that need additional information.

b. Modifying data: You can modify the data in the validate() method before returning it.
3. Related Concepts

A. Validators: For reusable validation logic, you can create custom validator functions.

B. UniqueTogetherValidator: This validator ensures that a combination of fields is unique.


C. Conditional validation: You can perform validation only if certain conditions are met.

D. Nested serializers: When using nested serializers, validation is applied to each nested
object as well.
Depth in Django Rest Framework Serializers

1. Basic Concept

The 'depth' option in Django Rest Framework serializers is used to control how many levels
of nested serialization should occur. It's a simple way to automatically serialize related
objects to a certain level without having to explicitly define nested serializers.

2. How to Use Depth

You can set the depth in the Meta class of your serializer:

In this example, 'depth = 1' means that the 'books' field (assuming it's a related field) will be
serialized one level deep.

3. Depth Levels
● depth = 0 (default): No nested serialization occurs.
● depth = 1: First level of related objects are serialized.
● depth = 2: First and second levels of related objects are serialized.
● And so on...
4. Example with Multiple Levels

Consider these models:


Now, let's create a serializer with depth:

With depth = 2, the serialized output might look like this:

Views

Django Rest Framework Views: A Comprehensive Guide

1. Introduction to Views in DRF

Views in Django Rest Framework are responsible for processing incoming


requests and returning appropriate responses. They define the logic for how
your API behaves.

2. Types of Views in DRF a. Function-Based Views (FBVs) b. Class-Based


Views (CBVs) c. Generic Views d. ViewSets
3. Function-Based Views (FBVs)
1. FBVs are the simplest form of views in DRF. They are Python functions
that take a request and return a response.

2. Class-Based Views (CBVs)


CBVs provide a way to organize code related to different HTTP methods into
separate methods on a class.

Example:

3. Generic Views
DRF provides a set of pre-built views for common operations. These include:

a. ListAPIView: For read-only endpoints to represent a collection of model


instances. b. CreateAPIView: For create-only endpoints. c. RetrieveAPIView:
For read-only endpoints to represent a single model instance. d.
DestroyAPIView: For delete-only endpoints for a single model instance. e.
UpdateAPIView: For update-only endpoints for a single model instance. f.
ListCreateAPIView: For read-write endpoints to represent a collection of model
instances. g. RetrieveUpdateAPIView: For read or update endpoints to
represent a single model instance. h. RetrieveDestroyAPIView: For read or
delete endpoints to represent a single model instance. i.
RetrieveUpdateDestroyAPIView: For read-write-delete endpoints to represent
a single model instance.

Example:

Difference between viewset and genericview

● Generic views are more granular. You typically use one view class per
endpoint.
● ViewSets group related views together and use "actions" to define
behavior.
● Generic views map directly to HTTP methods, while ViewSet actions
are typically mapped to HTTP methods in the URL router.
● Generic views are focused on a single type of operation, while ViewSets
combine multiple operations.

a. ListAPIView: This view is used to create a read-only endpoint for a


collection of model instances.

Example:
This view will return a list of all books in the database.

b. CreateAPIView: This view is used for create-only endpoints, allowing


clients to post new instances of a model.

Example:

This view will allow creating new Author instances.

c. RetrieveAPIView: This view is for read-only endpoints representing a


single model instance.

Example:
This view will return details of a specific book when given its primary key.

d. DestroyAPIView: This view is for delete-only endpoints for a single model


instance.

Example:

This view will allow deleting a specific comment.

e. UpdateAPIView: This view is for update-only endpoints for a single model


instance.

Example:

This view will allow updating a user's profile.


f. ListCreateAPIView: This view combines the functionalities of ListAPIView
and CreateAPIView, allowing both reading a collection and creating new
instances.

Example:

This view will allow listing all posts and creating new ones.

g. RetrieveUpdateAPIView: This view combines RetrieveAPIView and


UpdateAPIView, allowing reading and updating a single instance.

Example:

This view will allow retrieving details of a product and updating it.
h. RetrieveDestroyAPIView: This view combines RetrieveAPIView and
DestroyAPIView, allowing reading and deleting a single instance.

Example:

This view will allow retrieving details of an order and deleting it.

i. RetrieveUpdateDestroyAPIView: This view combines RetrieveAPIView,


UpdateAPIView, and DestroyAPIView, allowing reading, updating, and
deleting a single instance.

Example:

This view will allow retrieving, updating, and deleting a specific article.

These Generic Views significantly reduce the amount of code you need to
write for common operations in your API. They encapsulate the logic for
different HTTP methods (GET, POST, PUT, DELETE) and provide a consistent
interface for working with your models. By using these views, you can quickly
set up CRUD (Create, Read, Update, Delete) operations for your models with
minimal code.

4.ViewSets
ViewSets in DRF are classes that combine the logic for multiple related
views in a single class. They provide actions for standard list, create,
retrieve, update, and delete operations.

Key points:

● ViewSets reduce repetitive code


● They provide a consistent interface for common operations
● ViewSets are typically used with Routers, which automatically
generate URL patterns

Types of ViewSets
1. ViewSet
2. GenericViewSet
3. ModelViewSet
4. ReadOnlyModelViewSet

Let's explore each type in detail:

1. ViewSet

This is the base class for all ViewSet types. It doesn't provide any actions by
default.

Example:
Real-life scenario: A dashboard ViewSet that provides various statistics and
doesn't directly correspond to a single model.

2. GenericViewSet

Inherits from GenericAPIView and provides the base functionality for other
ViewSets. It doesn't include any actions by default.

Example:

Real-life scenario: An e-commerce platform where you want to list products


and allow creating new ones, but not editing or deleting them directly through
the API.
3. ModelViewSet

Provides a complete set of CRUD operations for a model.

Example:

Real-life scenario: A CRM system where you need full CRUD operations for
customer data.

4. ReadOnlyModelViewSet

Provides only 'read' operations (list and retrieve) for a model.

Example:

Real-life scenario: A blog where you want to expose published posts for
reading, but not allow editing or creating posts through the API.
Actions for viewsets

Things to know about actions

Actions are not exclusive to ModelViewSet:

● Actions can be used in various types of ViewSets, not just ModelViewSet.


● They are also available in generic ViewSets and custom ViewSets.

Main types of ViewSets:

● ViewSet: The base class for all ViewSets.


● GenericViewSet: Inherits from GenericAPIView and provides the base
functionality.
● ModelViewSet: Provides a complete set of CRUD operations.
● ReadOnlyModelViewSet: Provides only 'read' operations (list and retrieve).

ModelViewSet specifics:

● ModelViewSet is a convenience class that includes implementations for all


common actions.
● It inherits from GenericViewSet and includes mixins for Create, List, Retrieve,
Update, and Destroy actions.

Custom ViewSets:

● You can create custom ViewSets by inheriting from ViewSet or


GenericViewSet.
● In custom ViewSets, you define only the actions you need.

Action mapping:

● Actions are typically mapped to HTTP methods in the URL configuration.


● For example: 'list' is usually mapped to GET, 'create' to POST, etc.
Key ViewSet actions:
1. list
2. create
3. retrieve
4. update
5. partial_update
6. Destroy
Custom actions

Custom actions allow you to add additional endpoints to your ViewSet beyond
the standard create, retrieve, update, and delete operations.

1. Basic Structure: Custom actions are created by using the @action


decorator on methods within your ViewSet.
2. @action Decorator Parameters:

● methods: List of HTTP methods this action responds to.


● detail: Boolean indicating if this action is for a list or detail view.
● url_path: String to customize the URL path for this action.
● url_name: String to customize the URL name for this action.
● permission_classes: List of permission classes for this action.
● serializer_class: Serializer class for this action.

3. Types of Custom Actions:

a. Detail Actions (operates on a single instance):

b. List Actions (operates on the entire queryset):


4. Customizing URL Paths:

5. Adding Multiple HTTP Methods:

6. Using Different Serializers:


7. Adding Custom Permissions:

Mixins

Things to know about MIXINS

Purpose of Mixins:

● To provide reusable behavior that can be added to different classes.


● To break down complex functionality into smaller, manageable pieces.
● To adhere to the DRY (Don't Repeat Yourself) principle.

Common Mixins in DRF:

● ListModelMixin: Implements the list action.


● CreateModelMixin: Implements the create action.
● RetrieveModelMixin: Implements the retrieve action.
● UpdateModelMixin: Implements the update action.
● DestroyModelMixin: Implements the destroy action.
Mixins in Django REST Framework can be used with:

1. rest_framework.views.APIView
2. rest_framework.viewsets.GenericViewSet
3. rest_framework.generics.GenericAPIView
4. Any custom class-based views you create

● ModelViewSet composition: ModelViewSet is indeed a pre-composed set of


mixins.

It includes:

● CreateModelMixin
● RetrieveModelMixin
● UpdateModelMixin
● DestroyModelMixin
● ListModelMixin
● GenericViewSet

● No need to specify mixins: When using ModelViewSet, you don't need to


explicitly include these mixins because they're already there. The
ModelViewSet gives you all CRUD (Create, Retrieve, Update, Delete)
operations plus the List operation out of the box.

● With APIView: You typically wouldn't use the standard DRF model mixins.
Instead, you'd implement the methods yourself or use custom mixins that
don't rely on GenericAPIView's functionality.
● With custom views (like the Django View class): Again, the standard DRF
model mixins aren't suitable. You'd use custom mixins or implement the
functionality directly.
● The standard DRF mixins (CreateModelMixin, ListModelMixin, etc.) are
designed to work with GenericAPIView, not with the basic APIView or custom
views. This is because these mixins depend on certain methods and attributes
provided by GenericAPIView.
● The standard DRF mixins (CreateModelMixin, ListModelMixin, etc.) are
designed to work with classes that provide the functionality of
GenericAPIView, which includes both GenericAPIView itself and its
subclasses like GenericViewSet.
Key difference in usage:

● With GenericAPIView, you typically need to define the HTTP method handlers
(get, post, etc.) explicitly.
● With GenericViewSet, the viewset's as_view() method automatically maps
actions to HTTP methods based on the included mixins.

Usage with Different View Types

1. With APIView

APIView is the base class for views in DRF. Mixins can be used to add specific
functionalities.
2. With GenericAPIView

GenericAPIView extends APIView with common behavior for standard list and detail
views.
3. With ViewSets

ViewSets combine the logic for multiple related views in a single class.

4. With Custom Views

Mixins can be used with custom views to add specific behaviors.


ModelViewSet
ModelViewSet is a pre-composed set of mixins, providing full CRUD functionality.
Custom Mixins
You can create custom mixins for reusable functionality across different views.

QuerySet
● A queryset is a collection of database objects from your Django models.
It represents a database query but doesn't fetch the data until it's
needed.
● In DRF, the queryset attribute is used to specify which objects should be
used for CRUD operations in your API views.
● How is it implemented? It's typically set as a class attribute in your view:
What's its purpose?

● Defines the initial set of objects available to the view


● Used for retrieving objects in list views
● Used for looking up single objects in detail views
● Applies to all HTTP methods (GET, POST, PUT, DELETE)

What's its purpose?

● Defines the initial set of objects available to the view


● Used for retrieving objects in list views
● Used for looking up single objects in detail views
● Applies to all HTTP methods (GET, POST, PUT, DELETE)

Limitations:

● Static - doesn't change based on request data


● Can't easily implement dynamic filtering

get_queryset():
● Get_queryset is a method that returns a queryset of objects to be used
in the view.
● It's used to dynamically generate the queryset based on the current
request or other factors.
● How is it implemented? Override the get_queryset() method in your
view:

What's its purpose?

● Allows dynamic queryset generation


● Can filter based on request data, URL parameters, or user information
● Provides more flexibility than the static queryset attribute
Advantages:

● Dynamic - can change based on each request


● Allows complex filtering and customization
● Can implement permission-based filtering

When to use:

● When you need to filter objects based on the current user


● For implementing search or complex filtering
● When the queryset needs to change based on request data

Queryset and get_queryset() Clarification

These two work with various DRF generic views and viewsets. Let me clarify
this for you:

1. Class-based views that use querysets:

● ListAPIView
● RetrieveAPIView
● CreateAPIView
● UpdateAPIView
● DestroyAPIView
● ListCreateAPIView
● RetrieveUpdateAPIView
● RetrieveDestroyAPIView
● RetrieveUpdateDestroyAPIView

2. ViewSets:

● ModelViewSet
● ReadOnlyModelViewSet

All these views can use both the queryset attribute and the get_queryset()
method.
EXAMPLES :
In these examples:

● The queryset attribute sets the base queryset for the view.
● The get_queryset() method allows you to customise the queryset
dynamically, often based on the current request.
● For create operations, while queryset isn't directly used, it can still
be useful for permissions and other DRF features.

● APIView: APIView is the most basic view in DRF. It doesn't use


queryset or get_queryset() by default. You have to handle data
retrieval manually in your methods.

● GenericAPIView: GenericAPIView is designed to be used with


mixin classes. It does support queryset and get_queryset().

● GenericViewSet: GenericViewSet is a type of ViewSet that uses


the same interface as GenericAPIView. It supports both queryset
and get_queryset().

● ViewSet: The basic ViewSet doesn't use queryset or


get_queryset() by default. Like APIView, you need to handle data
retrieval manually.
Ordering

1. Filtering in Django Rest Framework

Description: Ordering in Django Rest Framework (DRF) allows you to sort


query results based on specific fields. It provides a flexible way to control the
order in which objects are returned in API responses.

Implementation: To implement ordering:

1. Import OrderingFilter from rest_framework.filters


2. Add OrderingFilter to the filter_backends in your view
3. Specify which fields can be used for ordering using the ordering_fields
attribute

Let's assume we have a Book model

With this setup, you can order books in various ways:

● By title (ascending): /api/books/?ordering=title


● By price (descending): /api/books/?ordering=-price
● By author then publication date:
/api/books/?ordering=author,publication_date
Filter

2. Filtering in Django Rest Framework

Filtering in DRF allows you to restrict the results of a query based on certain
criteria. It enables clients to request specific subsets of data that match given
conditions.

Implementation: To implement filtering:

1. Install django-filter: pip install django-filter


2. Add 'django_filters' to INSTALLED_APPS in settings.py
3. Import DjangoFilterBackend from django_filters.rest_framework
4. Add DjangoFilterBackend to the filter_backends in your view
5. Specify which fields can be used for filtering using the filterset_fields
attribute

With this setup, you can filter books:

● By author: /api/books/?author=J.K. Rowling


● By publication date: /api/books/?publication_date=2023-01-01
● By author and publication date: /api/books/?author=J.K.
Rowling&publication_date=2023-01-01
Combining Ordering and Filtering

DRF allows you to combine ordering and filtering, providing powerful data
manipulation capabilities to API clients.

Implementation: To implement both:

1. Import both OrderingFilter and DjangoFilterBackend


2. Add both to the filter_backends list
3. Specify both ordering_fields and filterset_fields

Now you can combine filtering and ordering:

● Filter by author and order by price: /api/books/?author=J.K.


Rowling&ordering=-price
● Filter by publication date and order by title:
/api/books/?publication_date=2023-01-01&ordering=titl
e
Search filter

Search Filter provides a simple way to implement search functionality across


multiple fields in your model.

Implementation:

1. Import SearchFilter from rest_framework.filters


2. Add SearchFilter to the filter_backends
3. Specify which fields to search using the search_fields attribute

This setup allows for searching across title and author fields:

● Search for "potter": /api/books/?search=potter


● Search for "rowling": /api/books/?search=rowling

The search will look for partial matches in both title and author fields.
Permissions

Permissions in Django Rest Framework

Overview: Permissions in DRF determine whether a request should be granted or


denied access. They are used to restrict access to views based on certain
conditions.

Types of Permissions: a. Object-level permissions b. View-level permissions

Built-in Permission Classes:

● AllowAny: Allows unrestricted access


● IsAuthenticated: Allows access to authenticated users only
● IsAdminUser: Allows access to admin users only
● IsAuthenticatedOrReadOnly: Allows read access to all, write access to
authenticated users
● DjangoModelPermissions: Ties into Django's standard model permissions
● DjangoObjectPermissions: For per-object permissions

Custom Permissions

● Create in permissions.py file


● Subclass rest_framework.permissions.BasePermission
● Override methods:
○ has_permission(self, request, view) for view-level
○ has_object_permission(self, request, view, obj) for object-level

Permission Checks:

● For views: Occurs before any other code in the view runs
● For objects: Occurs after the view's queryset has been filtered

Handling Permission Denied:

● DRF raises PermissionDenied or NotAuthenticated exceptions


● Can be customised using exception handlers

Permissions with Class-Based Views

● Use permission_classes attribute


● For function-based views, use @permission_classes decorator
Permissions with Viewsets

● Apply permissions to entire viewset or override per action

Applying Permissions:

● Globally: In settings.py

● Per-View: Using the permission_classes attribute

● Per-Method: Overriding get_permissions()


● Combining Permissions Use & (AND) and | (OR) operators:

Custom permission
Custom Permissions in Django Rest Framework

1. Introduction to Custom Permissions


○ Purpose: Create tailored access control beyond built-in permissions
○ Allow fine-grained control over who can access views or perform
actions
2. Creating Custom Permissions

a. Location: Create a permissions.py file in your app directory

b. Basic Structure:
Key Methods in Custom Permissions a. has_permission(self, request, view)

● For view-level permissions


● Called on every request
● Return True to allow access, False to deny

b. has_object_permission(self, request, view, obj)

● For object-level permissions


● Called only if has_permission returns True
● obj is the object being accessed
● Return True to allow access, False to deny

Examples of Custom Permissions

a. Role-Based Permission:

b. Object Ownership Permission:

c. Time-Based Permission:
Custom Permissions in ViewSets

● Apply to entire ViewSet or per action


Router
Routers in Django REST Framework are a powerful tool for automatically generating
URL patterns for your API views, particularly when working with ViewSets. They
simplify the process of URL configuration and promote consistency in your API
design.

Purpose of Routers:

● Automatically generate URL patterns for ViewSets


● Reduce boilerplate code in URL configuration
● Ensure consistent URL structure across your API

Basic Usage: To use a router, you typically follow these steps:

a. Import the router class:


Types of Routers: DRF provides several router classes:

a. SimpleRouter: The base router class

b. DefaultRouter: Extends SimpleRouter, adds a default API root view

c. CustomRouter: You can create your own by subclassing SimpleRouter or


DefaultRouter

DefaultRouter Features:

● Generates routes for standard CRUD operations


● Provides a browsable API root
● Appends format suffixes to URLs (e.g., .json, .api)

URL Patterns Generated: For a ViewSet named 'user', a DefaultRouter typically


generates these URL patterns:

● GET /users/ - list


● POST /users/ - create
● GET /users/{pk}/ - retrieve
● PUT /users/{pk}/ - update
● PATCH /users/{pk}/ - partial update
● DELETE /users/{pk}/ - destroy

Customizing Routes: You can customize routes using the @action decorator in
your ViewSet:

1. This creates a new route: POST /users/{pk}/set_password/


2. Reverse URL lookup: Routers provide names for URL reversing:
○ '{basename}-list' for the list view
○ '{basename}-detail' for the detail view
3. Nested Routers: While not part of DRF core, third-party packages like
drf-nested-routers allow you to create nested resource routes.
4. Benefits of Using Routers:
○ Consistency: Ensures a consistent URL structure
○ DRY principle: Reduces repetitive URL pattern definitions
○ Flexibility: Easy to add or modify routes
○ Integration: Works well with DRF's browsable API
5. Considerations:
○ Routers are best suited for ViewSets, not for individual APIViews
○ They may not be ideal for very custom or complex URL structures
○ You can mix router-generated URLs with manually defined URLs in
your project

Routers in DRF provide a convenient and powerful way to manage URL


configurations for your API, especially when working with ViewSets. They promote
best practices in API design and can significantly reduce the amount of boilerplate
code in your project.

Would you like me to elaborate on any specific aspect of routers in DRF?

Authentication
Authentication in DRF
Authentication is the process of verifying the identity of a user or system making a
request to an API. In DRF, it determines if a request should be permitted and
identifies the requester.

Types of Authentication
1. Basic Authentication
2. Session Authentication
3. Token Authentication
4. JWT Authentication
5. Custom Authentication
Detailed Explanation of Each Type
1. Basic Authentication
○ Uses HTTP Basic Auth
○ Sends credentials with each request
○ Implementation:

Logic:

● Client sends base64 encoded username:password in Authorization header


● DRF decodes and verifies credentials against Django's user model
● If valid, sets request.user and allows the request
2. Session Authentication

● Uses Django's session framework


● Suitable for AJAX clients that are running in the same session context as the
API
● Implementation:

Logic:

● User logs in through a form or API endpoint


● Django creates a session and stores the session ID in a cookie
● Subsequent requests include this cookie
● DRF verifies the session and retrieves the user
3. Token Authentication
○ Uses simple token-based HTTP Authentication scheme
○ Suitable for client-server setups, like native desktop or mobile clients
○ Implementation:

Logic:

● User obtains a token by sending credentials to a token endpoint


● Client includes the token in the Authorization header of requests
● DRF validates the token and identifies the user
4. JWT Authentication

● Uses JSON Web Tokens


● Stateless authentication mechanism
● Implementation (using djangorestframework-simplejwt):

Logic:

● User obtains a JWT by sending credentials


● Client includes the JWT in the Authorization header
● DRF decodes and validates the JWT, identifying the user
5. Custom Authentication

● Allows for unique authentication schemes


● Implementation:

Logic:

● Define a custom authentication class


● Implement the authenticate method to check credentials
● Return a (user, auth) tuple if authentication succeeds, or None if it fails
● Raise AuthenticationFailed for invalid credentials

You might also like