Tuesday, 22 June 2021

Django Rest Api(DRF)

Install using pip

CODE 
      pip install djangorestframework
    

Uninstall using pip

CODE 
      ppip uninstall djangorestframework
    

Installing DRF to Django Project

CODE 
      INSTALLED_APPS = [

    ...

    'rest_framework',

]
    

URL to use Browsable API

CODE 
      urlpatterns = [
      ...
      path(api-auth/, include('rest_framework.urls'))
  ]
    

Serializer and Serialization

Python JSON Python has a built in package called json, which is used to work with json data.

dumps(data) – This is used to convert python object into json string.

CODE 
      import json
      python_data = {'name': 'Sonam', 'roll':101 }
      json_data = json.dumps(python_data)
      print(json_data)
    

Output

{"name" : "Sonam", "roll" : 101}

loads(data) – This is used to parse json string.

CODE 
      import json
      json_data = {"name" : "Sonam", "roll" : 101}
      parsed_data = json.loads(json_data)
      print(parsed_data)
    

Output

{"name" : "Sonam", "roll" : 101}

Serializers

In Django REST Framework, serializers are responsible for converting complex data such as query sets and model instances to native Python datatypes.

Serializers are also responsible for deserialization which means it allows parsed data to be converted back into complex types.

Serializer Class

A serializer class is very similar to a Django Form and ModelForm class, and includes similar validation flags on the various fields, such as required, max_length and default.

How to Create Serializer Class

Create a separate seriealizers.py file to write all serializers.

serializers.py 
      from rest_framework import serializers
      class StudentSerializer(serializers.Serializer):
          name = serializers.CharField(max_length=100)
          roll = serializers.IntegerField()
          city = serializers.CharField(max_length=100)
    
models.py 
      from django.db import models
      class Student(models.Model):
         name = models.CharField(max_length=100)
         roll = models.IntegerField()
         city = models.CharField(max_length=100)
    

Run makemigrations and migrate command


The process of converting complex data such as querysets and model instances to native Python datatypes are called as Serialization in DRF.


Creating model instance stu

CODE 
      stu = Student.objects.get(id = 1)
    

Converting model instance stu to Python Dict / Serializing Object

CODE 
      serializer = StudentSerializer(stu)
    

Creating Query Set

CODE 
      stu = Student.objects.all()
    

Converting Query Set stu to List of Python Dict / Serializing Query Set

CODE 
      serializer = StudentSerializer(stu, many=True)
    

print(serializer.data)

JSONRenderer

This is used to render Serialized data into JSON which is understandable by Front End

CODE 
      Importing JSONRenderer
      from rest_framework.renderers import JSONRenderer

    

Render the Data into Json

CODE 
      json_data = JSONRenderer().render(serializer.data)
    
PROGRAM EXAMPLE gs1
myapp.py
import requests

URL = "http://127.0.0.1:8000/stuinfo"
# URL = "http://127.0.0.1:8000/stuinfo/1"


= requests.get(url = URL)

data = r.json()

print(data)
urls.py
from django.contrib import admin
from django.urls import path
from api import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('stuinfo/<int:pk>', views.student_detail),
    path('stuinfo/', views.student_list),
]

models.py
from django.db import models

# Create your models here.
class Student(models.Model):
 name = models.CharField(max_length=100)
 roll = models.IntegerField()
 city = models.CharField(max_length=100)
serializers.py
from rest_framework import serializers
class StudentSerializer(serializers.Serializer):
 id = serializers.IntegerField()
 name = serializers.CharField(max_length=100)
 roll = serializers.IntegerField()
 city = serializers.CharField(max_length=100)
views.py
from django.shortcuts import render
from .models import Student
from .serializers import StudentSerializer
from rest_framework.renderers import JSONRenderer
from django.http import HttpResponse, JsonResponse
# Model Object - Single Student Data

def student_detail(requestpk):
 stu = Student.objects.get(id = pk) # Complex DataType
 print(stu)
 serializer = StudentSerializer(stu)  # Python Native DataType
 json_data = JSONRenderer().render(serializer.data) # Render into Json
 return HttpResponse(json_data, content_type='application/json')
 # return JsonResponse(serializer.data)

# Query Set - All Student Data
def student_list(request):
 stu = Student.objects.all()
 # print(stu)
 serializer = StudentSerializer(stu, many=True)
 json_data = JSONRenderer().render(serializer.data)
 return HttpResponse(json_data, content_type='application/json')
 # return JsonResponse(serializer.data, safe=False)

3. De-serialization

Serializers are also responsible for deserialization which means it allows parsed data to be converted back into complex types, after first validating the incoming data. 

BytesIO( )

A stream implementation using an in-memory bytes buffer. It inherits BufferedIOBase. The buffer is discarded when the close() method is called.

import io

stream = io.BytesIO(json_data)

JSONParser( )

This is used to parse json data to python native data type.

from rest_framework.parsers import JSONParser

parsed_data = JSONParser().parse(stream)

De-serialization

Deserialization allows parsed data to be converted back into complex types, after first validating the incoming data.

Creating Serializer Object           

serializer = StudentSerializer(data = parsed_data)

Validated Data

serializer.is_valid()

serializer.validated_data

serializer.errors

Create Data/Insert Data

from rest_framework import serializers

class StudentSerializer(serializers.Serializer):

    name = serializers.CharField(max_length=100)

    roll = serializers.IntegerField()

    city = serializers.CharField(max_length=100)


   def create(self, validated_data):

              return Student.objects.create(**validated_data)

Update Data

from rest_framework import serializers

class StudentSerializer(serializers.Serializer):

    name = serializers.CharField(max_length=100)

    roll = serializers.IntegerField()

    city = serializers.CharField(max_length=100)


    def update(self, instance, validated_data):

              instance.name = validated_data.get('name', instance.name)

              instance.roll = validated_data.get('roll', instance.roll)

              instance.city = validated_data.get('city', instance.city)

              instance.save()

              return instance

Instance- Old Data stored in Database

validated_data- New Data from user for updation

Complete Update Data

serializer = StudentSerializer(stu, data=pythondata) 

if serializer.is_valid():

    serializer.save()

Partial Update Data

serializer = StudentSerializer(stu, data=pythondata, partial=True)

if serializer.is_valid():

    serializer.save()


PROGRAM EXAMPEL (Function based view)gs3

myapp.py

import requests
import json

URL = "http://127.0.0.1:8000/studentapi/"

def get_data(id = None):
 data = {}
 if id is not None:
  data = {'id':id}
 json_data = json.dumps(data)
 print("********")
 print(json_data)
 r = requests.get(url = URL, data = json_data)
 data = r.json()
 print(data)

# get_data()
# get_data(6)

def post_data():
 data = {
  'name':'Ravi',
  'roll':104,
  'city': 'Dhanbad'
 }

 json_data = json.dumps(data)
 r = requests.post(url = URL, data = json_data)
 data = r.json()
 print(data)

# post_data()

def update_data():
 data = {
  'id': 6,
  'name':'puspndu',
  'city': 'Ranchii'
 }

 json_data = json.dumps(data)
 r = requests.put(url = URL, data = json_data)
 data = r.json()
 print(data)

update_data()


def delete_data():
 data = { 'id': 5 }

 json_data = json.dumps(data)
 r = requests.delete(url = URL, data = json_data)
 data = r.json()
 print(data)

# delete_data()

urls.py

from django.contrib import admin
from django.urls import path
from api import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('studentapi/', views.student_api),
]


models.py

from django.db import models

# Create your models here.
class Student(models.Model):
 name = models.CharField(max_length=100)
 roll = models.IntegerField()
 city = models.CharField(max_length=100)

serializers.py

from rest_framework import serializers
from .models import Student

class StudentSerializer(serializers.Serializer):
 name= serializers.CharField(max_length=100)
 roll = serializers.IntegerField()
 city= serializers.CharField(max_length=100)

# create method implyment because we want to create
 def create(self, validated_data):
  return Student.objects.create(**validated_data)

# update method implyment because we want to update
 def update(self, instance, validated_data):
  # print(instance.name)
  instance.name = validated_data.get('name', instance.name)
  # print(instance.name)
  instance.roll = validated_data.get('roll', instance.roll)
  instance.city = validated_data.get('city', instance.city)
  instance.save()
  # print(instance)
  return instance

views.py

from django.shortcuts import render
import io
from rest_framework.parsers import JSONParser
from .models import Student
from .serializers import StudentSerializer
from rest_framework.renderers import JSONRenderer
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def student_api(request):
 if request.method == 'GET':
  json_data = request.body
  stream = io.BytesIO(json_data)
  pythondata = JSONParser().parse(stream)
  id = pythondata.get('id', None)
  if id is not None:
   stu = Student.objects.get(id=id)
   serializer = StudentSerializer(stu)
   json_data = JSONRenderer().render(serializer.data)
   return HttpResponse(json_data, content_type='application/json')

  stu = Student.objects.all()
  serializer = StudentSerializer(stu, many=True)
  json_data = JSONRenderer().render(serializer.data)
  return HttpResponse(json_data, content_type='application/json')
 
 if request.method == 'POST':
  json_data = request.body
  stream = io.BytesIO(json_data)
  pythondata = JSONParser().parse(stream)
  serializer = StudentSerializer(data = pythondata)
  if serializer.is_valid():
   serializer.save()
   res = {'msg': 'Data Created'}
   json_data = JSONRenderer().render(res)
   return HttpResponse(json_data, content_type='application/json')
  json_data = JSONRenderer().render(serializer.errors)
  return HttpResponse(json_data, content_type='application/json')

 if request.method == 'PUT':
  json_data = request.body
  stream = io.BytesIO(json_data)
  pythondata = JSONParser().parse(stream)
  # myapp.py thaka jata update korta chi sai "id" ta get kor66i
  id = pythondata.get('id')
  stu = Student.objects.get(id=id)
  #  Complete Update - Required All Data from Front End/Client
  #  serializer = StudentSerializer(stu, data=pythondata)

  #  Partial Update - All Data not required
  serializer = StudentSerializer(stu, data=pythondata, partial=True)
  if serializer.is_valid():
   serializer.save()
   res = {'msg':'Data Updated !!'}
   # Response Code
   json_data = JSONRenderer().render(res)
   return HttpResponse(json_data, content_type='application/json')
  json_data = JSONRenderer().render(serializer.errors)
  return HttpResponse(json_data, content_type='application/json')
 
 if request.method == 'DELETE':
  json_data = request.body
  stream = io.BytesIO(json_data)
  pythondata = JSONParser().parse(stream)
  id = pythondata.get('id')
  stu = Student.objects.get(id=id)
  stu.delete()
  res = {'msg': 'Data Deleted!!'}

  # json_data = JSONRenderer().render(res)
  # return HttpResponse(json_data, content_type='application/json')
  return JsonResponse(res, safe=False)

4. Validation

Validation

         Field Level Validation

         Object Level Validation

         Validators

Field Level Validation

We can specify custom field-level validation by adding validate_fieldName methods to your Serializer subclass.

validate_fieldName methods should return the validated value or raise a serializers.ValidationError

Syntax:- def validate_fieldname(self, value)

Example:- def validate_roll(self, value)

Where, value is the field value that requires validation.

 

from rest_framework import serializers

class StudentSerializer(serializers.Serializer):

              name = serializers.CharField(max_length=100)

              roll = serializers.IntegerField()

              city = serializers.CharField(max_length=100)

              def  validate_roll(self, value):

                            if value > = 200 :

                                          raise serializers.ValidationError(‘Seat Full’)

                            return value

Object Level Validation

When we need to do validation that requires access to multiple fields we do object level validation by adding a method called validate( ) to Serializer subclass.

It raises a serializers.ValidationError if necessary, or just return the validated values.

Syntax:- def validate (self, data)

Example:- def validate (self, data)

Where, data is a dictionary of field values.


from rest_framework import serializers

class StudentSerializer(serializers.Serializer):

              name = serializers.CharField(max_length=100)

              roll = serializers.IntegerField()

              city = serializers.CharField(max_length=100)

              def  validate(self, data):

                            nm = data.get(‘name’)

                            ct = data.get(‘city’)

                            if nm.lower() == ‘rohit’ and ct.lower() != ‘ranchi’ :

                                          raise serializers.ValidationError(‘City must be Ranchi’)

                            return data       

Validators

from rest_framework import serializers

def  starts_with_r(value):

              if value[‘0’].lower() != ‘r’ :

                            raise serializers.ValidationError(‘Name should start with R’)

class StudentSerializer(serializers.Serializer):

              name = serializers.CharField(max_length=100, validators=[starts_with_r])

              roll = serializers.IntegerField()

              city = serializers.CharField(max_length=100)

 

Validation Priority

         Validators

         Field Level Validation

         Object Level Validation


PROGRAM EXAMPLE (Class based view)gs5

myapp.py

import requests
import json

URL = "http://127.0.0.1:8000/studentapi/"

def get_data(id = None):
 data = {}
 if id is not None:
  data = {'id':id}
 json_data = json.dumps(data)
 r = requests.get(url = URLdata = json_data)
 data = r.json()
 print(data)

# get_data()

def post_data():
 data = {
  'name':'rohan',
  'roll':124,
  'city''bokaro'
 }

 json_data = json.dumps(data)
 r = requests.post(url = URLdata = json_data)
 data = r.json()
 print(data)

post_data()

def update_data():
 data = {
  'id'5,
  'name':'Jack',
  'city''Ranchi'
 }

 json_data = json.dumps(data)
 r = requests.put(url = URLdata = json_data)
 data = r.json()
 print(data)

# update_data()


def delete_data():
 data = { 'id'5 }

 json_data = json.dumps(data)
 r = requests.delete(url = URLdata = json_data)
 data = r.json()
 print(data)

# delete_data()



 urls.py

from django.contrib import admin
from django.urls import path
from api import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('studentapi/', views.StudentAPI.as_view()),
]

 models.py

from django.db import models

# Create your models here.
class Student(models.Model):
 name= models.CharField(max_length=100)
 roll = models.IntegerField()
 city= models.CharField(max_length=100)

serializers.py

from rest_framework import serializers
from .models import Student

# Validators
def start_with_r(value):
 if value[0].lower() != 'r':
  raise serializers.ValidationError('Name should be start with R')

class StudentSerializer(serializers.Serializer):
 name= serializers.CharField(max_length=100validators=[start_with_r])
 roll = serializers.IntegerField()
 city= serializers.CharField(max_length=100)

 def create(selfvalidated_data):
  return Student.objects.create(**validated_data)

 def update(selfinstancevalidated_data):
  # print(instance.name)
  instance.name = validated_data.get('name', instance.name)
  # print(instance.name)
  instance.roll = validated_data.get('roll', instance.roll)
  instance.city = validated_data.get('city', instance.city)
  instance.save()
  return instance

 # Field Lavel Validation
 def validate_roll(selfvalue):
  if value >= 200:
   raise serializers.ValidationError('Seat Full')
  return value

 # Object Level Validation
 def validate(selfdata):
  print(data)
  nm = data.get('name')
  ct = data.get('city')
  if nm.lower() == 'rohit' and ct.lower() != 'ranchi':
   raise serializers.ValidationError('City must be Ranchi')
  return data

views.py

from django.shortcuts import render
import io
from rest_framework.parsers import JSONParser
from .models import Student
from .serializers import StudentSerializer
from rest_framework.renderers import JSONRenderer
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.views import View

# Like this way we have to csrf_exempt for class based view
@method_decorator(csrf_exempt, name='dispatch')
class StudentAPI(View):
 def get(selfrequest*args**kwargs):
  json_data = request.body
  stream = io.BytesIO(json_data)
  pythondata = JSONParser().parse(stream)
  id = pythondata.get('id'None)
  if id is not None:
   stu = Student.objects.get(id=id)
   serializer = StudentSerializer(stu)
   json_data = JSONRenderer().render(serializer.data)
   return HttpResponse(json_data, content_type='application/json')

  stu = Student.objects.all()
  serializer = StudentSerializer(stu, many=True)
  json_data = JSONRenderer().render(serializer.data)
  return HttpResponse(json_data, content_type='application/json')

 def post(selfrequest*args**kwargs):
  json_data = request.body
  stream = io.BytesIO(json_data)
  pythondata = JSONParser().parse(stream)
  serializer = StudentSerializer(data = pythondata)
  if serializer.is_valid():
   serializer.save()
   res = {'msg''Data Created'}
   json_data = JSONRenderer().render(res)
   return HttpResponse(json_data, content_type='application/json')
  json_data = JSONRenderer().render(serializer.errors)
  return HttpResponse(json_data, content_type='application/json')

 def put(selfrequest*args**kwargs):
  json_data = request.body
  stream = io.BytesIO(json_data)
  pythondata = JSONParser().parse(stream)
  id = pythondata.get('id')
  stu = Student.objects.get(id=id)
  #  Complete Update - Required All Data from Front End/Client
  #  serializer = StudentSerializer(stu, data=pythondata) 
  
  #  Partial Update - All Data not required
  serializer = StudentSerializer(stu, data=pythondata, partial=True)
  if serializer.is_valid():
   serializer.save()
   res = {'msg':'Data Updated !!'}
   json_data = JSONRenderer().render(res)
   return HttpResponse(json_data, content_type='application/json')
  json_data = JSONRenderer().render(serializer.errors)
  return HttpResponse(json_data, content_type='application/json')

 def delete(selfrequest*args**kwargs):
  json_data = request.body
  stream = io.BytesIO(json_data)
  pythondata = JSONParser().parse(stream)
  id = pythondata.get('id')
  stu = Student.objects.get(id=id)
  stu.delete()
  res = {'msg''Data Deleted!!'}
  # json_data = JSONRenderer().render(res)
  # return HttpResponse(json_data, content_type='application/json')
  return JsonResponse(res, safe=False)


Function Based View

views.py

from django.shortcuts import render
import io
from rest_framework.parsers import JSONParser
from .models import Student
from .serializers import StudentSerializer
from rest_framework.renderers import JSONRenderer
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def student_api(request):
 if request.method == 'GET':
  json_data = request.body
  stream = io.BytesIO(json_data)
  pythondata = JSONParser().parse(stream)
  id = pythondata.get('id'None)
  if id is not None:
   stu = Student.objects.get(id=id)
   serializer = StudentSerializer(stu)
   json_data = JSONRenderer().render(serializer.data)
   return HttpResponse(json_data, content_type='application/json')

  stu = Student.objects.all()
  serializer = StudentSerializer(stu, many=True)
  json_data = JSONRenderer().render(serializer.data)
  return HttpResponse(json_data, content_type='application/json')
 
 if request.method == 'POST':
  json_data = request.body
  stream = io.BytesIO(json_data)
  pythondata = JSONParser().parse(stream)
  serializer = StudentSerializer(data = pythondata)
  if serializer.is_valid():
   serializer.save()
   res = {'msg''Data Created'}
   json_data = JSONRenderer().render(res)
   return HttpResponse(json_data, content_type='application/json')
  json_data = JSONRenderer().render(serializer.errors)
  return HttpResponse(json_data, content_type='application/json')

 if request.method == 'PUT':
  json_data = request.body
  stream = io.BytesIO(json_data)
  pythondata = JSONParser().parse(stream)
  # myapp.py thaka jata update korta chi sai "id" ta get kor66i
  id = pythondata.get('id')
  stu = Student.objects.get(id=id)
  #  Complete Update - Required All Data from Front End/Client
  #  serializer = StudentSerializer(stu, data=pythondata) 

  #  Partial Update - All Data not required
  serializer = StudentSerializer(stu, data=pythondata, partial=True)
  if serializer.is_valid():
   serializer.save()
   res = {'msg':'Data Updated !!'}
   # Response Code
   json_data = JSONRenderer().render(res)
   return HttpResponse(json_data, content_type='application/json')
  json_data = JSONRenderer().render(serializer.errors)
  return HttpResponse(json_data, content_type='application/json')
  
 if request.method == 'DELETE':
  json_data = request.body
  stream = io.BytesIO(json_data)
  pythondata = JSONParser().parse(stream)
  id = pythondata.get('id')
  stu = Student.objects.get(id=id)
  stu.delete()
  res = {'msg''Data Deleted!!'}

  # json_data = JSONRenderer().render(res)
  # return HttpResponse(json_data, content_type='application/json')
  return JsonResponse(res, safe=False)

        5. Model Serializer

ModelSerializer Class

The ModelSerializer class provides a shortcut that lets you automatically create a Serializer class with fields that correspond to the Model fields.

         It will automatically generate a set of fields for you, based on the model.

         It includes simple default implementations of create() and update().

Create ModelSerializer Class

Create a separate seriealizers.py file to write all serializers

from rest_framework import serializers

class StudentSerializer(serializers.ModelSerializer):

    class Meta:

              model = Student

              fields = [‘id’, ‘name’, ‘roll’, ‘city’]

            #  fields = ‘__all__’

       # exclude = [‘roll’]

 ----------------------------------------------------

One Field for read only

from rest_framework import serializers

class StudentSerializer(serializers.ModelSerializer):

    name = serializers.CharField(read_only=True)

    class Meta:

              model = Student

              fields = [‘id’, ‘name’, ‘roll’, ‘city’]


Multipule Field for read only

class StudentSerializer(serializers.ModelSerializer):

     class Meta:

              model = Student

              fields = [‘id’, ‘name’, ‘roll’, ‘city’]

              read_only_fields = [‘name’, ‘roll’]

or

from rest_framework import serializers

class StudentSerializer(serializers.ModelSerializer):

     class Meta:

              model = Student

              fields = [‘id’, ‘name’, ‘roll’, ‘city’]

              extra_kwargs = {‘name': {‘read_only': True}}


read_only- we can’t update because read only.

PROGRAM EXAMPLE (gs7)

serializers.py

from rest_framework import serializers
from .models import Student

class StudentSerializer(serializers.ModelSerializer):
 # name = serializers.CharField(read_only=True)
 class Meta:
  model = Student
  fields = ['name', 'roll', 'city']
  # read_only_fields = ['name', 'roll']
  extra_kwargs = {'name':{'read_only':True}}

 

ModelSerializer Validation

from rest_framework import serializers

class StudentSerializer(serializers.ModelSerializer):

     class Meta:

              model = Student

              fields = [‘id’, ‘name’, ‘roll’, ‘city’]

     def  validate_roll(self, value):

              if value > = 200 :

                        raise serializers.ValidationError(‘Seat Full’)

              return value

PROGRAM EXAMPLE(Field level,Object level,Validators) gs8

 from rest_framework import serializers
from .models import Student

class StudentSerializer(serializers.ModelSerializer):
# Validators
# aka akhana likta hoba
 def start_with_r(value):
  if value[0].lower() != 'r':
   raise serializers.ValidationError('Name should be start with R')

 name = serializers.CharField(validators=[start_with_r])
 
 class Meta:
   model = Student
   fields = ['name''roll''city']

 # Field Level Validation
 def validate_roll(selfvalue):
  if value >= 200:
   raise serializers.ValidationError('Seat Full')
  return value

 # Object Level Validation
 def validate(selfdata):
  nm = data.get('name')
  ct = data.get('city')
  if nm.lower() == 'veeru' and ct.lower() != 'ranchi':
   raise serializers.ValidationError('City must be Ranchi')
  return data


 **********************************************

6. Function Based APIView


Function Based api_view

By default only GET methods will be accepted. Other methods will respond with "405 Method Not Allowed".

@api_view()

 

@api_view([‘GET’, ‘POST’, ‘PUT’, ‘DELETE’])

def function_name(request):

     ……………….

     ……………….

 

Methods

         GET

         POST

         PUT

         PATCH

         DELETE

Check example gs10

***From here used Browseble API start ************

 PROGRAM EXAMPLE gs11

models.py

from django.db import models

# Create your models here.
class Student(models.Model):
 name = models.CharField(max_length=50)
 roll = models.IntegerField()
 city = models.CharField(max_length=50)

serializers.py

from rest_framework import serializers
from .models import Student

class StudentSerializer(serializers.ModelSerializer):
 class Meta:
  model = Student
  fields = ['id''name''roll''city']

urls.py

from django.contrib import admin
from django.urls import path
from api import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('studentapi/', views.student_api),
    path('studentapi/<int:pk>/', views.student_api),
]

views.py

from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Student
from .serializers import StudentSerializer
from rest_framework import status
# Create your views here.

@api_view(['GET''POST''PUT''PATCH''DELETE'])
def student_api(requestpk=None):
 if request.method == 'GET':
  id = pk
  if id is not None:
   stu = Student.objects.get(id=id)
   serializer = StudentSerializer(stu)
   return Response(serializer.data)

  stu = Student.objects.all()
  serializer = StudentSerializer(stu, many=True)
  return Response(serializer.data)

 if request.method == 'POST':
  serializer = StudentSerializer(data=request.data)
  if serializer.is_valid():
   serializer.save()
   return Response({'msg':'Data Created'}, status=status.HTTP_201_CREATED)
  return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 if request.method == 'PUT':
  id = pk
  stu = Student.objects.get(pk=id)
  serializer = StudentSerializer(stu, data=request.data)
  if serializer.is_valid():
   serializer.save()
   return Response({'msg':'Complete Data Updated'})
  return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 if request.method == 'PATCH':
  id = pk
  stu = Student.objects.get(pk=id)
  serializer = StudentSerializer(stu, data=request.data, partial=True)
  if serializer.is_valid():
   serializer.save()
   return Response({'msg':'Partial Data Updated'})
  return Response(serializer.errors)

 if request.method == 'DELETE':
  id = pk
  stu = Student.objects.get(pk=id)
  stu.delete()
  return Response({'msg':'Data Deleted'})


                    7. Class Based APIView

Class Based APIView

from rest_framework.views import APIView

class StudentAPI(APIView):

   def get(self, request, format=None):

        stu = Student.objects.all()

        serializer = StudentSerializer(stu, many=True)

        return Response(serializer.data)

    def post(self, request, format=None):

        serializer = StudentSerializer(data=request.data)

        if serializer.is_valid():

            serializer.save()

            return Response({‘msg’: ‘Data Created’ }, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

  PROGRAM EXAMPLE

views.py

from django.shortcuts import render
from rest_framework.response import Response
from .models import Student
from .serializers import StudentSerializer
from rest_framework import status
from rest_framework.views import APIView
# Create your views here.

class StudentAPI(APIView):
 def get(selfrequestpk=Noneformat=None):
  id = pk
  if id is not None:
   stu = Student.objects.get(id=id)
   print(stu)
   serializer = StudentSerializer(stu)
   print(serializer.data)
   return Response(serializer.data)

  stu = Student.objects.all()
  serializer = StudentSerializer(stu, many=True)
  return Response(serializer.data)

 def post(selfrequestformat=None):
  serializer = StudentSerializer(data=request.data)
  if serializer.is_valid():
   serializer.save()
   return Response({'msg':'Data Created'}, status=status.HTTP_201_CREATED)
  return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 def put(selfrequestpkformat=None):
  id = pk
  stu = Student.objects.get(pk=id)
  serializer = StudentSerializer(stu, data=request.data)
  if serializer.is_valid():
   serializer.save()
   return Response({'msg':'Complete Data Updated'})
  return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 def patch(selfrequestpkformat=None):
  id = pk
  stu = Student.objects.get(pk=id)
  serializer = StudentSerializer(stu, data=request.data, partial=True)
  if serializer.is_valid():
   serializer.save()
   return Response({'msg':'Partial Data Updated'})
  return Response(serializer.errors)

 def delete(selfrequestpkformat=None):
  id = pk
  stu = Student.objects.get(pk=id)
  stu.delete()
  return Response({'msg':'Data Deleted'})

                  8. Generic API View and Mixins

  1.          ListModelMixin
  2.          CreateModelMixin
  3.          RetrieveModelMixin
  4.          UpdateModelMixin
  5.   5.    DestroyModelMixin

 

  PROGRAM EXAMPLE(gs13)

All Mixin Different Different

urls.py

from django.contrib import admin
from django.urls import path
from api import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('studentapi/', views.StudentList.as_view()),
    # path('studentapi/', views.StudentCreate.as_view()),
    # path('studentapi/<int:pk>/', views.StudentRetrive.as_view()),
    # path('studentapi/<int:pk>/', views.StudentUpdate.as_view()),
    path('studentapi/<int:pk>/', views.StudentDestroy.as_view()),
]

views.py

# GenericAPIView and Model Mixin
from .models import Student
from .serializers import StudentSerializer
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin

class StudentList(GenericAPIViewListModelMixin):
 queryset = Student.objects.all()
 serializer_class = StudentSerializer

 def get(selfrequest*args**kwargs):
  return self.list(request, *args, **kwargs)

class StudentCreate(GenericAPIViewCreateModelMixin):
 queryset = Student.objects.all()
 serializer_class = StudentSerializer

 def post(selfrequest*args**kwargs):
  return self.create(request, *args, **kwargs)

class StudentRetrive(GenericAPIViewRetrieveModelMixin):
 queryset = Student.objects.all()
 serializer_class = StudentSerializer

 def get(selfrequest*args**kwargs):
  return self.retrieve(request, *args, **kwargs)

class StudentUpdate(GenericAPIViewUpdateModelMixin):
 queryset = Student.objects.all()
 serializer_class = StudentSerializer

 def put(selfrequest*args**kwargs):
  return self.update(request, *args, **kwargs)

class StudentDestroy(GenericAPIViewDestroyModelMixin):
 queryset = Student.objects.all()
 serializer_class = StudentSerializer

 def delete(selfrequest*args**kwargs):
  return self.destroy(request, *args, **kwargs)

 PROGRAM EXAMPLE(gs14)

All Mixin Togathere

urls.py

from django.contrib import admin
from django.urls import path
from api import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('studentapi/', views.LCStudentAPI.as_view()),
    path('studentapi/<int:pk>/', views.RUDStudentAPI.as_view()),
]

views.py

# GenericAPIView and Model Mixin
from .models import Student
from .serializers import StudentSerializer
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin

# List and Create - PK Not Required
class LCStudentAPI(GenericAPIViewListModelMixinCreateModelMixin):
 queryset = Student.objects.all()
 serializer_class = StudentSerializer

 def get(selfrequest*args**kwargs):
  return self.list(request, *args, **kwargs)

 def post(selfrequest*args**kwargs):
  return self.create(request, *args, **kwargs)

# Retrieve Update and Destroy - PK Required
class RUDStudentAPI(GenericAPIViewRetrieveModelMixinUpdateModelMixinDestroyModelMixin):
 queryset = Student.objects.all()
 serializer_class = StudentSerializer

 def get(selfrequest*args**kwargs):
  return self.retrieve(request, *args, **kwargs)

 def put(selfrequest*args**kwargs):
  return self.update(request, *args, **kwargs)

 def delete(selfrequest*args**kwargs):
  return self.destroy(request, *args, **kwargs)


               9. Generic API View and Mixins

Concrete View Class

         ListAPIView

         CreateAPIView

         RetrieveAPIView

         UpdateAPIView

         DestroyAPIView

 

         ListCreateAPIView

         RetrieveUpdateAPIView

         RetrieveDestroyAPIView

         RetrieveUpdateDestroyAPIView

 PROGRAM EXAMPLE(gs15)

Usefull

urls.py

from django.contrib import admin
from django.urls import path
from api import views
urlpatterns = [
    path('admin/', admin.site.urls),
    # path('studentapi/', views.StudentList.as_view()),
    # path('studentapi/', views.StudentCreate.as_view()),
    # path('studentapi/<int:pk>/', views.StudentRetrieve.as_view()),
    # path('studentapi/<int:pk>/', views.StudentUpdate.as_view()),
    # path('studentapi/<int:pk>/', views.StudentDestroy.as_view()),

    path('studentapi/', views.StudentListCreate.as_view()),
    # path('studentapi/<int:pk>/', views.StudentRetrieveUpdate.as_view()),
    # path('studentapi/<int:pk>/', views.StudentRetrieveDestroy.as_view()),
    path('studentapi/<int:pk>/', views.StudentRetrieveUpdateDestroy.as_view()),
]

views.py

from .models import Student
from .serializers import StudentSerializer
from rest_framework.generics import ListAPIView, CreateAPIView, RetrieveAPIView, UpdateAPIView, DestroyAPIView, ListCreateAPIView, RetrieveUpdateAPIView, RetrieveDestroyAPIView, RetrieveUpdateDestroyAPIView


class StudentList(ListAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer

class StudentCreate(CreateAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer

class StudentRetrieve(RetrieveAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer

class StudentUpdate(UpdateAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer

class StudentDestroy(DestroyAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer

class StudentListCreate(ListCreateAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer

class StudentRetrieveUpdate(RetrieveUpdateAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer

class StudentRetrieveDestroy(RetrieveDestroyAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer

class StudentRetrieveUpdateDestroy(RetrieveUpdateDestroyAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer

10. ViewSet

ViewSet

A ViewSet class is simply a type of class-based View, that does not provide any method handlers such as get() or post(), and instead provides actions such as list() and create().

         list() – Get All Records.

         retrieve() – Get Single Record

         create() – Create/Insert Record

         update() – Update Record Completely

         partial_update() – Update Record Partially

         destroy() – Delete Record

 

ViewSet Class

from rest_framework import viewsets

class StudentViewSet(viewsets.ViewSet):

    def list(self, request): ………

    def create(self, request):  ……….

    def retrieve(self, request, pk=None): ………

    def update(self, request, pk=None): ……….

    def partial_update(self, request, pk=None): ………

    def destroy(self, request, pk=None): ……..

 

During dispatch, the following attributes are available on the ViewSet:-

         basename - the base to use for the URL names that are created.

         action - the name of the current action (e.g., list, create).

         detail - boolean indicating if the current action is configured for a list or detail view.

         suffix - the display suffix for the viewset type - mirrors the detail attribute.

         name - the display name for the viewset. This argument is mutually exclusive to suffix.

         description - the display description for the individual view of a viewset.

 


 PROGRAM EXAMPLE(gs17)-->must examin in vscode
urls.py
from django.contrib import admin
from django.urls import path, include
from api import views
from rest_framework.routers import DefaultRouter

# Creating Router Object
router = DefaultRouter()

# Register StudentViewSet with Router
router.register('studentapi', views.StudentViewSet, basename='student')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),

]

views.py

from django.shortcuts import render
from rest_framework.response import Response
from .models import Student
from .serializers import StudentSerializer
from rest_framework import status
from rest_framework import viewsets


class StudentViewSet(viewsets.ViewSet):
 def list(selfrequest):
  print("*********List***********")
  print("Basename:", self.basename)
  print("Action:", self.action)
  print("Detail:", self.detail)
  print("Suffix:", self.suffix)
  print("Name:", self.name)
  print("Description:", self.description)
  stu = Student.objects.all()
  serializer = StudentSerializer(stu, many=True)
  return Response(serializer.data)

 def retrieve(selfrequestpk=None):
  print("*********Retrieve***********")
  print("Basename:", self.basename)
  print("Action:", self.action)
  print("Detail:", self.detail)
  print("Suffix:", self.suffix)
  print("Name:", self.name)
  print("Description:", self.description)
  id = pk
  if id is not None:
   stu = Student.objects.get(id=id)
   serializer = StudentSerializer(stu)
   return Response(serializer.data)

 def create(selfrequest):
  print("*********Create***********")
  print("Basename:", self.basename)
  print("Action:", self.action)
  print("Detail:", self.detail)
  print("Suffix:", self.suffix)
  print("Name:", self.name)
  print("Description:", self.description)
  serializer = StudentSerializer(data=request.data)
  if serializer.is_valid():
   serializer.save()
   return Response({'msg':'Data Created'}, status=status.HTTP_201_CREATED)
  return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 def update(self,requestpk):
  print("*********Update***********")
  print("Basename:", self.basename)
  print("Action:", self.action)
  print("Detail:", self.detail)
  print("Suffix:", self.suffix)
  print("Name:", self.name)
  print("Description:", self.description)
  id = pk
  stu = Student.objects.get(pk=id)
  serializer = StudentSerializer(stu, data=request.data)
  if serializer.is_valid():
   serializer.save()
   return Response({'msg':'Complete Data Updated'})
  return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 def partial_update(self,requestpk):
  print("*********Partial Update***********")
  print("Basename:", self.basename)
  print("Action:", self.action)
  print("Detail:", self.detail)
  print("Suffix:", self.suffix)
  print("Name:", self.name)
  print("Description:", self.description)
  id = pk
  stu = Student.objects.get(pk=id)
  serializer = StudentSerializer(stu, data=request.data, partial=True)
  if serializer.is_valid():
   serializer.save()
   return Response({'msg':'Partial Data Updated'})
  return Response(serializer.errors)

 def destroy(self,requestpk):
  print("*********Destroy***********")
  print("Basename:", self.basename)
  print("Action:", self.action)
  print("Detail:", self.detail)
  print("Suffix:", self.suffix)
  print("Name:", self.name)
  print("Description:", self.description)
  id = pk
  stu = Student.objects.get(pk=id)
  stu.delete()
  return Response({'msg':'Data Deleted'})

                  11. ModelViewSet Class(ge18)

User can list,retrive,create,update,delete korta parba.
list---> All data
retrive---->1 user ar data



urls.py
from django.contrib import admin
from django.urls import path, include
from api import views
from rest_framework.routers import DefaultRouter

# Creating Router Object
router = DefaultRouter()

# Register StudentViewSet with Router
router.register('studentapi', views.StudentModelViewSet, basename='student')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),

]

views.py
from .models import Student
from .serializers import StudentSerializer
from rest_framework import viewsets

class StudentModelViewSet(viewsets.ModelViewSet):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
ReadOnlyModelViewSet Class(gs19)
User can list,retrive korta parba.
urls.py
from django.contrib import admin
from django.urls import path, include
from api import views
from rest_framework.routers import DefaultRouter

# Creating Router Object
router = DefaultRouter()

# Register StudentViewSet with Router
router.register('studentapi', views.StudentReadOnlyModelViewSet, basename='student')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),

]

views.py
from .models import Student
from .serializers import StudentSerializer
from rest_framework import viewsets

class StudentReadOnlyModelViewSet(viewsets.ReadOnlyModelViewSet):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
 
     12. Basic Authentication and Permission

Why use Authentication & Permission?

Currently our API doesn't have any restrictions on who can edit or delete Data.

·        Data is always associated with a creator.

         Only authenticated users may create Data.

         Only the creator of a Data may update or delete it.

         Unauthenticated requests should have full read-only access.

Authentication Type

         BasicAuthentication

         SessionAuthentication

         TokenAuthentication

         RemoteUserAuthentication

         Custom authentication

BasicAuthentication

Permission Classes:
AllowAny: ja ku access korta para Authenticated and Unauthenticated user.

jodi globally declare kora hoy kono permission class ta hola views.py file sub class a apply hoya jaba, jodi kono class r permission change korta chi si class  a tahola ja permission apply korta chi66i sata si class a likta hoba.
IsAuthenticated: Register user( Authenticated user) login kora API ka access korta par ba(get,update,delete).
IsAdminUser: Only Staff Status=True Access korta parba API ka
IsAuthenticatedOrReadOnly: Register user( Authenticated user) login kora API ka access korta par ba(get,update,delete). UnRegister user( UnAuthenticated user) only data read korta parba.
DjangoModelPermissions: Must ba required register user( Authenticated user) and
POST requests require the user to have the add permission on the model.
PUT and PATCH requests require the user to have the change permission on the model.
DELETE requests require the user to have the delete permission on the model.
DjangoModelPermissionsOrAnonReadOnly: Must ba required register user( Authenticated user) and
POST requests require the user to have the add permission on the model.
PUT and PATCH requests require the user to have the change permission on the model.
 DELETE requests require the user to have the delete permission on the model.
UnRegister user( UnAuthenticated user) only data read korta parba.
Custom Permissions


BasicAuthentication(gs20)
urls.py
from django.contrib import admin
from django.urls import path, include
from api import views
from rest_framework.routers import DefaultRouter

# Creating Router Object
router = DefaultRouter()

# Register StudentViewSet with Router
router.register('studentapi', views.StudentModelViewSet, basename='student')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
]

views.py
from .models import Student
from .serializers import StudentSerializer
from rest_framework import viewsets
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated, AllowAny, IsAdminUser

class StudentModelViewSet(viewsets.ModelViewSet):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
  authentication_classes=[BasicAuthentication]
  permission_classes=[IsAuthenticated]
  # permission_classes=[AllowAny]
  # permission_classes=[IsAdminUser]


settings.py
Implement how to used global permission

SessionAuthentication(gs21)

urls.py
from django.contrib import admin
from django.urls import path, include
from api import views
from rest_framework.routers import DefaultRouter

# Creating Router Object
router = DefaultRouter()

# Register StudentViewSet with Router
router.register('studentapi', views.StudentModelViewSet, basename='student')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),

    # nichar ta na likla login, logout a sub asba na(session Authantication)
    path('auth/', include('rest_framework.urls'namespace='rest_framework'))

]
views.py
from .models import Student
from .serializers import StudentSerializer
from rest_framework import viewsets
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated, AllowAny, IsAdminUser, IsAuthenticatedOrReadOnly, DjangoModelPermissions, DjangoModelPermissionsOrAnonReadOnly

class StudentModelViewSet(viewsets.ModelViewSet):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
  authentication_classes=[SessionAuthentication]
  permission_classes=[IsAuthenticated]
  # permission_classes=[AllowAny]
  # permission_classes=[IsAdminUser]
  # permission_classes=[IsAuthenticatedOrReadOnly]
  permission_classes=[DjangoModelPermissions]
  # permission_classes=[DjangoModelPermissionsOrAnonReadOnly]



Custom Permissions

To implement a custom permission, override BasePermission and implement either, or both, of the following methods:

         has_permission(self, request, view)

         has_object_permission(self, request, view, obj)

The methods should return True if the request should be granted access, and False otherwise.

Program Example gs22

 custompermissions.py

from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):
 def has_permission(selfrequestview):

  #  User Only data dhakta paba But POST,PUT,DELETE korta parba na
  # if request.method == 'GET':
  #  return True
  # return False

  # Only user data POST korta parba
  if request.method == 'POST':
   return True
  return False


views.py
from .models import Student
from .serializers import StudentSerializer
from rest_framework import viewsets
from rest_framework.authentication import SessionAuthentication
from .custompermissions import MyPermission

class StudentModelViewSet(viewsets.ModelViewSet):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
  authentication_classes=[SessionAuthentication]
  permission_classes=[MyPermission]


# Here used SessionAuthentication, we can used BasicAuthentication also



Function Based view how to use Authentication And permission 
                                Programme Example gs23
urls.py
from django.contrib import admin
from django.urls import path
from api import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('studentapi/', views.student_api),
    path('studentapi/<int:pk>/', views.student_api),
]

views.py

from django.shortcuts import render
from rest_framework.response import Response
from .models import Student
from .serializers import StudentSerializer
from rest_framework import status
from rest_framework.authentication import BasicAuthentication
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import IsAuthenticated
# Create your views here.

@api_view(['GET', 'POST', 'PUT', 'PATCH', 'DELETE'])
@authentication_classes([BasicAuthentication])
@permission_classes([IsAuthenticated])
def student_api(request, pk=None):
 if request.method == 'GET':
  id = pk
  if id is not None:
   stu = Student.objects.get(id=id)
   serializer = StudentSerializer(stu)
   return Response(serializer.data)

  stu = Student.objects.all()
  serializer = StudentSerializer(stu, many=True)
  return Response(serializer.data)

 if request.method == 'POST':
  serializer = StudentSerializer(data=request.data)
  if serializer.is_valid():
   serializer.save()
   return Response({'msg':'Data Created'}, status=status.HTTP_201_CREATED)
  return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 if request.method == 'PUT':
  id = pk
  stu = Student.objects.get(pk=id)
  serializer = StudentSerializer(stu, data=request.data)
  if serializer.is_valid():
   serializer.save()
   return Response({'msg':'Complete Data Updated'})
  return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 if request.method == 'PATCH':
  id = pk
  stu = Student.objects.get(pk=id)
  serializer = StudentSerializer(stu, data=request.data, partial=True)
  if serializer.is_valid():
   serializer.save()
   return Response({'msg':'Partial Data Updated'})
  return Response(serializer.errors)

 if request.method == 'DELETE':
  id = pk
  stu = Student.objects.get(pk=id)
  stu.delete()
  return Response({'msg':'Data Deleted'})

TokenAuthentication

TokenAuthentication ka implement karar janna amara Browseble API used korta parbo na karan kono tarika nai used kara, ar janna amra httpie used karbo for request send(GET, POST, PUT, PATCH, DELETE)

INSTALLED_APPS = [

         ...

    'rest_framework.authtoken’

]

Note: Make sure to run manage.py migrate after changing your settings.

Note: If you use TokenAuthentication in production you must ensure that your API is only available over https.


Generate Token 

How to generate tocken programmer gs24 ppt-16(6)

Like this way programmer generate token

1. Using Admin panal token generate

step-1: login korta hoba superUser ar madhama admin panal

step-2: Admin panal a gya token add korta hoba, dila automatically tocken generate hoya jaba

2. Using tarminal token generate

step-1: Akta tarminal a django server run korta hoba.

step-2: Ar ak ta tartminal a nichar comment ta run korata hoba.

syntax: python manage.py drf_create_token <username> 

Ex: python manage.py drf_create_token user1

step-3: Dya addmin panal a check korta hoba token generate hoya66a kina. 

Token generate hoya ga66a, jodi abar Run kara hoy comment a token generate ar janna tahola token generate hoba na, generate token show korba.


How to generate token user(End user/client) gs25(ppt-16(7))

step1: configure following code

from rest_framework.authtoken.views import obtain_auth_token

urlpatterns = [

    path(‘gettoken/', obtain_auth_token)

]

*Developer check karar janna developer ka trminal used korta hoba 

step2: pip install httpie (For developer code implementnt)

step-3: Akta tarminal a django server run korta hoba.

step-4: Ar ak ta tartminal a nichar comment ta run korata hoba username and password ar sanga.

http POST http://127.0.0.1:8000/gettoken/ username=“name” password=“pass”

-----------------------------------------------------------------------------------------------------------------------------------------------------------

Uprar step flow hoba, uprar stapa sudhu amra "tocken" pa66i, jodi amra chi aro more information client/end user ka dita tahola Custom Auth Token implement korta hoba

Programming example gs26

auth.py

from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response

class CustomAuthToken(ObtainAuthToken):
 def post(self, request, *args, **kwargs):
  serializer = self.serializer_class(data=request.data, context={'request': request})
  serializer.is_valid(raise_exception=True)
  user = serializer.validated_data['user']
  token, created = Token.objects.get_or_create(user=user)
  return Response({
    'token': token.key,
     'user_id': user.pk,
     'email': user.email
  })

url a "CustomAuthToken" used korta hoba "obtain_auth_token" badala

urls.py

from django.contrib import admin
from django.urls import path, include
from api import views
from rest_framework.routers import DefaultRouter
from api.auth import CustomAuthToken

# Creating Router Object
router = DefaultRouter()

# Register StudentViewSet with Router
router.register('studentapi', views.StudentModelViewSet, basename='student')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
    path('auth/', include('rest_framework.urls', namespace='rest_framework')),
    path('gettoken/', CustomAuthToken.as_view())
]



Generate Token by Signals gs27

Using Signals-User create holy token generate hoya jaba.

jodi amra chi user jakhan create ho66a sai somoy token automatically generate korta, tahola signal used korta hoba

modeles.py

from django.db import models
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token

# Create your models here.
class Student(models.Model):
 name = models.CharField(max_length=50)
 roll = models.IntegerField()
 city = models.CharField(max_length=50)

# This Signal creates Auth Token for Users
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False,**kwargs):
 if created:
  Token.objects.create(user=instance)

GET Request

http http://127.0.0.1:8000/studentapi/

gs28

GET Request with Auth

http http://127.0.0.1:8000/studentapi/ 'Authorization:Token 621cdf999d9151f9aea8e52f00eb436aa680fa24’


POST Request/ Submitting Form

http -f POST http://127.0.0.1:8000/studentapi/ name=Jay roll=104 city=Dhanbad 'Authorization:Token 621cdf999d9151f9aea8e52f00eb436aa680fa24'

 

PUT Request

http PUT http://127.0.0.1:8000/studentapi/4/ name=Kunal roll=109 city=Bokaro 'Authorization:Token 621cdf999d9151f9aea8e52f00eb436aa680fa24’


Delete Request

http DELETE http://127.0.0.1:8000/studentapi/4/ 'Authorization:Token 621cdf999d9151f9aea8e52f00eb436aa680fa24’

 

JSON Web Token (JWT) (inpronent Authantication)gs30

Third party package we have to install

JWT Authentication doesn't need to use a database to validate a token.

How to Install Simple JWT

pip install djangorestframework-simplejwt

Configure Simple JWT

Use: Check kora user authenticate a66a kina

JWT Implement 3 Improtent concept:

1) Generate Token: After Generate token, We get Refresh and Access token , by default Access Token validaty 5 minute and refresh token validaty 1 day.

2) Refresh Token: when Access token ar validaty expayer hoya jai refresh token used kora amra access token paya thaki, ar fala user ka token generate karar projon hoy na.

3) Access Token: aka used kora amra janta pai token expayer vhoya ga66a kina.

setting.py(gs30): Jodi Acces  token and refresh token ar validaty bara ta chi implimat kora hoya66a.

ACCESS_TOKEN_LIFETIME: specifies how long access tokens are valid.(ACCESS_TOKEN jata paua jaba tar validity kata khan thakba ta amra define kori.)

REFRESH_TOKEN_LIFETIME: specifies how long refresh tokens are valid.(REFRESH_TOKEN ar validity kata khan thakba ta amra define kori.)

ROTATE_REFRESH_TOKENS :

True : REFRESH karar pora ACCESS_TOKEN and REFRESH_TOKEN poua jaba.

False: REFRESH karar pora only one token poua jaba that is ACCESS_TOKEN.

urls.py

from django.contrib import admin
from django.urls import path, include
from api import views
from rest_framework.routers import DefaultRouter
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView, TokenVerifyView
# Creating Router Object
router = DefaultRouter()

# Register StudentViewSet with Router
router.register('studentapi', views.StudentModelViewSet, basename='student')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
    path('gettoken/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('refreshtoken/', TokenRefreshView.as_view(), name='token_refresh'),
    path('verifytoken/', TokenVerifyView.as_view(), name='token_verify'),
]

Use JWT

GET Token(Token generate hoba)

http POST http://127.0.0.1:8000/gettoken/ username="user1" password="geekyshows"

Verify Token

http POST http://127.0.0.1:8000/verifytoken/ token="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjAzNjIxOTAxLCJqdGkiOiI2NmM4ZWJiYjUwMWM0MzA3YWJjMGNjNTY2ZmNmNTJiMyIsInVzZXJfaWQiOjJ9.cwUSWrkFnFdO8fP45aEP6GDa3yaybSVYAG6vGUlkFOo"

Refresh Token

http POST http://127.0.0.1:8000/refreshtoken/ refresh="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6M

TYwMzcwODAwMSwianRpIjoiYzYzODBmYjVjMDk3NDVhNjkyYzA5YWRmMGI1ZDQ5OWIiLCJ1c2VyX2lkIjoyfQ.Q-E-8N8VvSZof5IjoNIL-2KECRLqlYzBojbTCj_4dBc"

Token used korta hoba access token for request(GET, POST, PUT, PATCH, DELETE)

GET Request with Auth

http http://127.0.0.1:8000/studentapi/ 'Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjAzNjIxOTAxLCJqdGkiOiI2NmM4ZWJiYjUwMWM0MzA3YWJjMGNjNTY2ZmNmNTJiMyIsInVzZXJfaWQiOjJ9.cwUSWrkFnFdO8fP45aEP6GDa3yaybSVYAG6vGUlkFOo'

POST Request/ Submitting Form

http -f POST http://127.0.0.1:8000/studentapi/ name=Jay roll=104 city=Dhanbad 'Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjAzNjIxOTAxLCJqdGkiOiI2NmM4ZWJiYjUwMWM0MzA3YWJjMGNjNTY2ZmNmNTJiMyIsInVzZXJfaWQiOjJ9.cwUSWrkFnFdO8fP45aEP6GDa3yaybSVYAG6vGUlkFOo'

PUT Request

http PUT http://127.0.0.1:8000/studentapi/4/ name=Kunal roll=109 city=Bokaro 'Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjAzNjIxOTAxLCJqdGkiOiI2NmM4ZWJiYjUwMWM0MzA3YWJjMGNjNTY2ZmNmNTJiMyIsInVzZXJfaWQiOjJ9.cwUSWrkFnFdO8fP45aEP6GDa3yaybSVYAG6vGUlkFOo'

Delete Request

http DELETE http://127.0.0.1:8000/studentapi/4/ 'Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjAzNjIxOTAxLCJqdGkiOiI2NmM4ZWJiYjUwMWM0MzA3YWJjMGNjNTY2ZmNmNTJiMyIsInVzZXJfaWQiOjJ9.cwUSWrkFnFdO8fP45aEP6GDa3yaybSVYAG6vGUlkFOo'

settings.py

from datetime import timedelta
SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME':timedelta(minutes=10),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS':True,
}

Throttling(gs31)

ü  Authantikated user 1 day kata bar request korat parba and Unauthanticated user 1 day kata bar request korta par ba ta amra ai throtting ar sahaja implement korta parbo.

ü  Ata amadar API boot thaka rakha paba.

AnonRateThrottle: For anonomas user

UserRateThrottle:  For register user

       Globaly set(settinges.py):

The default throttling policy may be set globally, using the DEFAULT_THROTTLE_CLASSES and DEFAULT_THROTTLE_RATES settings. For example.

REST_FRAMEWORK = {

    'DEFAULT_THROTTLE_CLASSES': [

        'rest_framework.throttling.AnonRateThrottle',

        'rest_framework.throttling.UserRateThrottle'

    ],

    'DEFAULT_THROTTLE_RATES': {

        'anon': '100/day',# anon user(Unathanticated user) 1day 100 bar request korata parba.

        'user': '1000/day'# user(athanticated user) 1day 1000 bar request korata parba.

    }

}

Note:- The rate descriptions used in DEFAULT_THROTTLE_RATES may include second, minute, hour or day as the throttle period.

Browserl api ta test korbo refresh ar madhama

    1. Implement for register user 1day 2time request korta parba 

    views.py 

from .models import Student
from .serializers import StudentSerializer
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.authentication import SessionAuthentication
from rest_framework.throttling import AnonRateThrottle, UserRateThrottle

class StudentModelViewSet(viewsets.ModelViewSet):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
  authentication_classes=[SessionAuthentication]
  permission_classes=[IsAuthenticatedOrReadOnly]
  throttle_classes = [AnonRateThrottle, UserRateThrottle]

     settings.py

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES':{
        'anon': '2/day',
        'user': '5/hour',
    }
}

   2. Jodi alda alda API ta alda alda Throttling concept used korta chi tahola nich java implement kora hoya 66a savaba used korta hoba gs31

    throttling.py

from rest_framework.throttling import UserRateThrottle

class JackRateThrottle(UserRateThrottle):
 scope = 'jack'
 

views.py

from .models import Student
from .serializers import StudentSerializer
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.authentication import SessionAuthentication
from rest_framework.throttling import AnonRateThrottle, UserRateThrottle
from api.throttling import JackRateThrottle

class StudentModelViewSet(viewsets.ModelViewSet):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
  authentication_classes=[SessionAuthentication]
  permission_classes=[IsAuthenticatedOrReadOnly]
  # throttle_classes = [AnonRateThrottle, UserRateThrottle]
  throttle_classes = [AnonRateThrottle, JackRateThrottle]
 

 settings.py

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES':{
        'anon': '2/day',
        'user': '5/hour',
        'jack': '3/minute'
    }
}


ScopedRateThrottle: API ar ak ak part ka(GET, POST, PUT, PATCH, DELETE) throtal korta parbo(gs32)

views.py

from .models import Student
from .serializers import StudentSerializer
from rest_framework.generics import ListAPIView, CreateAPIView, RetrieveAPIView, UpdateAPIView, DestroyAPIView
from rest_framework.throttling import ScopedRateThrottle

class StudentList(ListAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
  throttle_classes = [ScopedRateThrottle]
  throttle_scope = 'viewstu'

class StudentCreate(CreateAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
  throttle_classes = [ScopedRateThrottle]
  throttle_scope = 'modifystu'

class StudentRetrieve(RetrieveAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
  throttle_classes = [ScopedRateThrottle]
  throttle_scope = 'viewstu'

class StudentUpdate(UpdateAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
  throttle_classes = [ScopedRateThrottle]
  throttle_scope = 'modifystu'

class StudentDestroy(DestroyAPIView):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
  throttle_classes = [ScopedRateThrottle]
throttle_scope = 'modifystu' 

 urls.py

from django.contrib import admin
from django.urls import path
from api import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('studentapi/', views.StudentList.as_view()),
    # path('studentapi/', views.StudentCreate.as_view()),
    # path('studentapi/<int:pk>/', views.StudentRetrieve.as_view()),
    # path('studentapi/<int:pk>/', views.StudentUpdate.as_view()),
    # path('studentapi/<int:pk>/', views.StudentDestroy.as_view()),
]

settings.py

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES':{
        'viewstu': '5/hour',
        'modifystu': '2/day'
    }
}

Filtering

·        Filter mana user ka data dhaka ta hoba filter kora (user only data dhakta paba user post,put,delete operation korta parba na, ar janna views.py file a ListView ka implement kora hoya66a)

# Ja User login thakba tar data access hoba gs33

from django.shortcuts import render
from .serializers import StudentSerializer
from rest_framework.generics import ListAPIView
from .models import Student
# Create your views here.

# Ja User login thakba tar data access hoba

class StudentList(ListAPIView):
 queryset = Student.objects.all()
 serializer_class = StudentSerializer
 def get_queryset(self):
  user = self.request.user
  return Student.objects.filter(passby=user)

DjangoFilterBackend

The django-filter library includes a DjangoFilterBackend class which supports highly customizable field filtering for REST framework.

To use DjangoFilterBackend, first we have to install django-filter.

pip install django-filter

Then add 'django_filters' to Django's INSTALLED_APPS:

INSTALLED_APPS = [

     'django_filters’,

]

Global Setting: Jata view thakba sub a apply hoya jaba (gs34)

REST_FRAMEWORK = {

    'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']

}

 views.py

from django.shortcuts import render
from .serializers import StudentSerializer
from rest_framework.generics import ListAPIView
from .models import Student
from django_filters.rest_framework import DjangoFilterBackend
# Create your views here.

class StudentList(ListAPIView):
 queryset = Student.objects.all()
 serializer_class = StudentSerializer
 # filterset_fields = ['city']
 filterset_fields = ['name','city']

settinges.py

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS':['django_filters.rest_framework.DjangoFilterBackend']
}

Per View Setting(alda alda view ta filter ka anable karar janna) gs34

You can set the filter backends on a per-view, or per-viewset basis, using the GenericAPIView class-based views.

from django_filters.rest_framework import DjangoFilterBackend

class StudentList(ListAPIView):

    queryset = Student.objects.all()

    serializer_class = StudentSerializer

    filter_backends = [DjangoFilterBackend]

    filterset_fields = [‘name', ‘city’]

Jar name sonam and jar city ranchi tar data ka filter kora dhakhou… a tar url hoba nicher t

 views.py

from django.shortcuts import render
from .serializers import StudentSerializer
from rest_framework.generics import ListAPIView
from .models import Student
from django_filters.rest_framework import DjangoFilterBackend
# Create your views here.

class StudentList(ListAPIView):
 queryset = Student.objects.all()
 serializer_class = StudentSerializer
 filter_backends = [DjangoFilterBackend]
 
 # filterset_fields = ['city']
 filterset_fields = ['name','city']

http://127.0.0.1:8000/studentapi/?name=Sonam&city=Ranchi
Output


search_fields gs35

views.py

from django.shortcuts import render
from .serializers import StudentSerializer
from rest_framework.generics import ListAPIView
from .models import Student
from rest_framework.filters import SearchFilter

class StudentList(ListAPIView):
 queryset = Student.objects.all()
 serializer_class = StudentSerializer
 filter_backends = [SearchFilter]
 search_fields = ['city']
#  search_fields = ['name','city']
#  search_fields = ['^name']



#  search_fields = ['^name']---> name ar first charecter likla, first cheracter sanga ja sub name match hoba saguli show korba
Output:


Ordering_fields gs36

views.py

from django.shortcuts import render
from .serializers import StudentSerializer
from rest_framework.generics import ListAPIView
from .models import Student
from rest_framework.filters import OrderingFilter

class StudentList(ListAPIView):
 queryset = Student.objects.all()
 serializer_class = StudentSerializer
 filter_backends = [OrderingFilter]
 ordering_fields = ['name']
#  ordering_fields = ['name', 'city']


Output:




Pagination

Pagination

         PageNumberPagination

         LimitOffsetPagination

         CursorPagination

 

PageNumberPagination

 

Gs37

Pagination Global Setting

The pagination style may be set globally, using the DEFAULT_PAGINATION_CLASS and PAGE_SIZE setting keys.

REST_FRAMEWORK = {

    ‘DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination. PageNumberPagination’,

    ‘PAGE_SIZE’: 5

}

 

Gs38

PageNumberPagination

class MyPageNumberPagination(PageNumberPagination):

    page_size = 5

    page_size_query_param = ‘records'

    max_page_size = 7

class StudentList(ListAPIView):

   queryset = Student.objects.all()

   serializer_class = StudentSerializer

   pagination_class = MyPageNumberPagination

 

 

This pagination style accepts a single number page number in the request query parameters.

To enable the PageNumberPagination style globally, use the following configuration, and set the PAGE_SIZE as desired:

REST_FRAMEWORK = {

    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',

    'PAGE_SIZE’: 5

}

http://127.0.0.1:8000/studentapi/?page=3

 

 

gs38

 page_size = 5--à ak page a koto guli record show korta chi66i

 page_query_param = 'p' -à http://127.0.0.1:8000/studentapi/?page=2 ‘page’ ka change korta chila amara define korbo jata ami pager badala likta chi66i(p)

 page_size_query_param = 'records'--à client ka power daoua hoiba 1 paga client kata guli record dhakta chi,

http://127.0.0.1:8000/studentapi/?p=2&records=10 ai url a hit korala client ak page a 10 record dhakta paba.( &records=10)

 max_page_size = 7-à specify kora hoy ak page a maximum kata guli record dhakta paba client

 

LimitOffsetPagination

Limit--- limit means kata guli record amra dhakta pabo

Offset--- Kon record thaka suru korbo record dhakana

 

To enable the LimitOffsetPagination style globally, use the following configuration:

REST_FRAMEWORK = {

    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination’

}

 

Gs39

http://127.0.0.1:8000/studentapi/?limit=4&offset=6

 

 default_limit = 5--à ak paga kata guli item dhaka bo sata set korta parbo without using limit and offset.

 limit_query_param = 'mylimit'-à ‘limit’ name change kora amra amadar pachandar name used korta parbo.

 offset_query_param = 'myoffset'à ‘offset’ name change kora amra amadar pachandar name used korta parbo.

http://127.0.0.1:8000/studentapi/?limit=4&offset=6

to

http://127.0.0.1:8000/studentapi/?mylimit=4&myoffset=6

 

 max_limit = 6----- maximum ak page a 6 record dhakta pabo

 

gs40

CursorPagination

Only next and previous button amara paya thak.  next and previous button ar madhama a ka control kora jai.

 page_size = 5--à ak page a kata guli record dhakta chi66i

 ordering = 'name'-à name ar basis a order hoba….. ording must be likta hoba nahola error asba.

cursor_query_param = 'cu'-à url a ‘cursor’ ar badala ‘cu’ used hoba. Following example

http://127.0.0.1:8000/studentapi/?cursor=cD1KYXk%3D

to

http://127.0.0.1:8000/studentapi/?cu=cD1KYXk%3D

 

 

 

Authentication Views



Server

 Python manage.py runserver ===> It is used for Development server, it has good feature auto restart when we are add or edit smoothing d...