DJANGO REST FRAMEWORK
concepts of django rest framework: -
dumps(data) = convert python object to json string
python_data = {‘name’: ‘sarita’}
json_data = json.dumps(python_data)
print(json_data )
o/p - {“name” : “sarita”}
loads(data) = used to parse json string
json_data = {“name” : “sarita”}
parsed_data = json.loads(json_data)
print(parsed_data )
o/p - {‘name’: ‘sarita’}
serializers: -
serializers converts complex data such as queryset and model object to native python datatypes
serializers allows parsed data to be converted back to complex data after validating incoming data.
--- our task is to convert model objects (every row is a object) into json data. (serialization)
--- firstly complex data is being passed into serializer which converts it into python native datatype.
--- python native datatype is a dict for single model object and orderdict for queryset as a complex data input.
--- python native data type will then be rendered into json data using jsonrenderer.
--- and the json data will be sent as response at last.
Steps of serialization: -
--- create model instance:-
stu = Student.objects.get(id = 1)
--- convert model instance to python dict (serializing object)
serializer = StudentSerializer(stu)
--- create QuerySet:-
stu = Student.objects.all()
--- convert QuerySet to list of python dict or orderdict (serializing QuerySet)
serializer = StudentSerializer(stu, many = True)
we can access serialized data using serializer.data.
JSONRenderer: - used to render serialized data into JSON.
--- Render the data into JSON.
json_data = JSONRenderer().render(serializer.data)
JsonResponse: - it renders serialized data into json and sends response.
# while get request is being hit
def student_info(request, pk):
# according to request retriving data from database using get query
data = Student.objects.get(id=pk)
# model instance(object) or queryset is being converted into python native data(either dict or orderdict)
serializer = StudentSerializer(data)
# serializer.data will give us dict or orderdict
print(serializer.data)
# jsonrenderer will convert python data into json data
json_data = JSONRenderer().render(serializer.data)
# json data will be sent using http response
return HttpResponse(json_data, content_type='application/json')
# using json response will directly convert python to json and send response
# return JsonResponse(serializer.data)
third party app --- Front-end app to send request
# to send get request and get data from web app
# the request will be send using below url
URL = "http://127.0.0.1:8000/api/stu_info/1"
# sending get request using requests module and getting response back in r variable
r = requests.get(url=URL)
# returns json encoded content of response
data = r.json()
print(data)
De-serialization: -
--- it converts parsed data to complex data type after validating data.
--- firstly json data will be parsed to python native data type which will then be converted into complex data type using serializer.
JSONParser(): - used to parse json data to python native data type.
parsed_data: - JSONParser().parse(stream)
--- Create serializer object: -
serializer = StudentSerializer(data = parsed_data)
--- Validated_data: -
serializer.is_valid() - checks if data is valid or not.
--- serializer.errors: -
raise error if data is invalid.
--- create method: - for creating records in database or when we need to use post method for any data submission, we need to write create method.
--- it takes validated_data and creates objects of respected models using validated_data which is submitted with post request.
# Mark a view function as being exempt from the CSRF view protection
@csrf_exempt
# when post request is hit from front-end
def student_create(request):
# check if request is post
if request.method == 'POST':
# using body attribute of request take json data in a variable
json_data = request.body
# print(json_data)
---- b'{"name": "Rahul", "roll": "107", "city": "Ramgadh"}'
# stream json data using byteIO
stream = io.BytesIO(json_data)
# print(stream)
---- <_io.BytesIO object at 0x7fd2946990a0>
# using json parser convert json data into python native data type
python_data = JSONParser().parse(stream)
# print(python_data)
--- {'name': 'Rahul', 'roll': '107', 'city': 'Ramgadh'}
# serializer converts python native data type into complex data type (either model object or queryset)
serializer = StudenSerializer(data=python_data)
# print(serializer.data)
--- {'name': 'Rahul', 'roll': 107, 'city': 'Ramgadh'}
# it checks if the complex data are valid or not
if serializer.is_valid():
print(serializer.is_valid())
# if data is valid it saves data into database
serializer.save()
# as a result we need to send response, here it is as python dict
res = {'msg': 'Data created successfully'}
# we need to send response as json so JSONRenderer will convert it into json
json_res = JSONRenderer().render(res)
# json res will be sent using HttpResponse here
return HttpResponse(json_res,
content_type='application/json')
json_error = JSONRenderer().render(serializer.errors)
return HttpResponse(json_error, content_type='application/json')
3rd party app --- Front-end app to send request
# to send post request to submit data to any web app
URL = "http://127.0.0.1:8000/api/stu_create/"
# the data in form of python object
data = {'name': 'Rahul', 'roll': '107', 'city': 'surat'}
# convert python to json formated string
json_data = json.dumps(data)
# print(json_data)
--- {"name": "Rahul", "roll": "107", "city": "Ramgadh"}
# send json data using post request
r = requests.post(url=URL, data=json_data)
# print(r) -
-- <Response [200]>
# returns json encoded content of response
r_data = r.json()
print(r_data)
To create Django project
In terminal, run command
- django-admin startproject <project_name>
let say:
- django-admin startproject DRF
To create new app
In terminal, run command
- python manage.py startapp api
- After creating app, include rest_framework and api in INSTALLED_APP list
- To store data in database we will create models in models.py file
from django.db import models
# Create your models here.
Class Singer(models.Model):
name = models.CharField(max_length=100)
gender=models.CharField(max_length=100)
def __str__(self):
return self.name
class Song(models.Model):
title = models.CharField(max_length=100)
singer = models.ForeignKey(Singer, on_delete=
models.CASCADE, related_name='sungby')
duration = models.IntegerField()
def __str__(Self):
return self.title
then we will register our model in admin.py file
from django.contrib import admin
from .models import Singer, Song
# Register your models here.
@admin.register(Singer)
class SingerAdmin(admin.ModelAdmin):
list_display = ['id', 'name', 'gender']
@admin.register(Song)
class SongAdmin(admin.ModelAdmin):
list_display = ['id', 'title', 'singer', 'duration']
then to create database tables we will run
commands
- python manage.py makemigrations
- python manage.py migrate
to create superuser
- python manage.py createsuperuser
create serializers.py file for writing serializers
from .models import Singer, Song
from rest_framework import serializers
class SongSerializer(serializers.ModelSerializer):
class Meta:
model = Song
fields = ['id', 'title', 'singer', 'duration']
class SingerSerializer(serializers.ModelSerializer):
class Meta:
model = Singer
fields = ['id', 'name', 'gender']
now we will write views in views.py file
from django.shortcuts import render
from .serializers import
SingerSerializer, SongSerializer
from rest_framework import viewsets
from .models import Singer, Song
class SingerViewSet(viewsets.ModelViewSet):
queryset = Singer.objects.all()
serializer_class = SingerSerializer
class SongSerializer(viewsets.ModelViewSet):
queryset = Song.objects.all()
serializer_class = SongSerializer
Problems and solutions
when I started django
1 Attribute error :-
when I used get_or_create method because those object which are not present in database we tried to acces
str has no attribute get
2. once I tried to access data dynamically but everything was working but
I forgot to put key and I put value instead
3. once instead of list in urls.py file I passed in set
Operational error :
set has not....
4. once I wrote staticfile instead STATICFILES_DIR so image were not loading
5. in git I had problem while pushing it was showing old accout so I changed it using
git config --global --replace-all user.name
git config --global --replace-all user.email
and check it using git config user.name
refer codewithharry for more information
6. for adding slug field refer to url_shortner project.
7. html table data colum size fixing using table-layout:fixed and colspan:2
8. for hiding any block element and show check css display block functionality
9. adding url using hyperlinkedidentityfield requires lookup properly in
view class and serializer class look_up field should be same and and if
you do not have that field(look_up) use pk otherwise it will show you
error. Model(Tweet) has no obj (tweet_id).
And dont pass name of include url as well as app_specific url, say if you have
in project file
path('api/tweet/',include('tweet.urls'),name='tweet'),
in app.urls file
path('api/tweet/<int:pk>/',TweetDetailView.as_view(),name='detail'),
then in view_name of HyperlinkedIdentityField pass
url = serializers.HyperlinkedIdentityField(view_name='detail',lookup_field='pk')