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"
r = 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 (request , pk ):
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 = URL , data = 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 = URL , data = 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 = 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.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 = 100 , validators = [start_with_r])
roll = serializers.IntegerField()
city= serializers.CharField(max_length = 100 )
def create (self , validated_data ):
return Student.objects.create(** validated_data)
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()
return instance
# Field Lavel Validation
def validate_roll (self , value ):
if value >= 200 :
raise serializers.ValidationError('Seat Full' )
return value
# Object Level Validation
def validate (self , data ):
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 (self , request , * 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 (self , request , * 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 (self , request , * 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 (self , request , * 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 (self , value ):
if value >= 200 :
raise serializers.ValidationError('Seat Full' )
return value
# Object Level Validation
def validate (self , data ):
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 (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' })
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 (self , request , pk = None , format = 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 (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 )
def put (self , request , pk , format = 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 (self , request , pk , format = 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 (self , request , pk , format = None ):
id = pk
stu = Student.objects.get(pk = id )
stu.delete()
return Response({'msg' :'Data Deleted' })
8 . Generic API View and Mixins
ListModelMixin CreateModelMixin RetrieveModelMixin UpdateModelMixin 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(GenericAPIView , ListModelMixin ):
queryset = Student.objects.all()
serializer_class = StudentSerializer
def get (self , request , * args , ** kwargs ):
return self.list(request, * args, ** kwargs)
class StudentCreate(GenericAPIView , CreateModelMixin ):
queryset = Student.objects.all()
serializer_class = StudentSerializer
def post (self , request , * args , ** kwargs ):
return self.create(request, * args, ** kwargs)
class StudentRetrive(GenericAPIView , RetrieveModelMixin ):
queryset = Student.objects.all()
serializer_class = StudentSerializer
def get (self , request , * args , ** kwargs ):
return self.retrieve(request, * args, ** kwargs)
class StudentUpdate(GenericAPIView , UpdateModelMixin ):
queryset = Student.objects.all()
serializer_class = StudentSerializer
def put (self , request , * args , ** kwargs ):
return self.update(request, * args, ** kwargs)
class StudentDestroy(GenericAPIView , DestroyModelMixin ):
queryset = Student.objects.all()
serializer_class = StudentSerializer
def delete (self , request , * 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(GenericAPIView , ListModelMixin , CreateModelMixin ):
queryset = Student.objects.all()
serializer_class = StudentSerializer
def get (self , request , * args , ** kwargs ):
return self.list(request, * args, ** kwargs)
def post (self , request , * args , ** kwargs ):
return self.create(request, * args, ** kwargs)
# Retrieve Update and Destroy - PK Required
class RUDStudentAPI(GenericAPIView , RetrieveModelMixin , UpdateModelMixin , DestroyModelMixin ):
queryset = Student.objects.all()
serializer_class = StudentSerializer
def get (self , request , * args , ** kwargs ):
return self.retrieve(request, * args, ** kwargs)
def put (self , request , * args , ** kwargs ):
return self.update(request, * args, ** kwargs)
def delete (self , request , * 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)),
]
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 (self , request ):
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 (self , request , pk = 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 (self , request ):
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 ,request , pk ):
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 ,request , pk ):
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 ,request , pk ):
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 (self , request , view ):
# 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: A kta 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: A kta 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