drf serialization component
Basic use
from django.urls import re_path
urlpatterns = [
re_path(r'books/$', views.BookView.as_view()),
re_path(r'books/(?P<pk>\d+)/$', views.BookFilterView.as_view()),
]
from rest_framework import serializers
class BookSerializer(serializers.Serializer):
title = serializers.CharField(max_length=32)
# Foreign key field
publish_name = serializers.CharField(max_length=32, source="publish.name", read_only=True)
# Many to many fields
authors_list = serializers.SerializerMethodField(read_only=True)
def get_authors_list(self, book_obj):
authors_queryset = book_obj.authors.all()
return [{"id":author.id, "name":author.name} for author in authors_queryset]
# Method called when adding data
def create(self, validated_data):
# {'title': 'Python666', 'price': Decimal('66.00'), 'publish': '2'}
validated_data['publish_id'] = validated_data.pop('publish')
book = Book.objects.create(**validated_data)
return book
# Method called when updating data
def update(self, instance, validated_data):
# Update data calls this method
instance.title = validated_data.get('title', instance.title)
instance.publishDate = validated_data.get('publishDate', instance.publishDate)
instance.price = validated_data.get('price', instance.price)
instance.publish_id = validated_data.get('publish', instance.publish.nid)
instance.save()
return instance
from rest_framework.response import Response
from rest_framework.views import APIView
class BookView(APIView):
# Get all
def get(self, request):
books = Book.objects.all()
serialized_data = BookSerializer(books, many=True)
return Response(serialized_data.data)
# New data
def post(self, request):
origin_data = request.data
serialized_data = BookSerializer(data=origin_data)
if serialized_data.is_valid():
serialized_data.save()
# Return new data
return Response(serialized_data.data)
else:
# Return error message
return Response(serialized_data.errors)
class BookFilterView(APIView):
# Update data
def put(self, request, pk):
origin_data = request.data # Modified data
obj = Book.objects.get(pk=pk)
serialized_data = BookSerializer(data=origin_data, instance=obj)
if serialized_data.is_valid():
serialized_data.save()
# Return modified data
return Response(serialized_data.data)
else:
return Response(serialized_data.errors)
# Delete data
def delete(self, request, id):
book_obj = Book.objects.get(pk=id).delete()
return Response("")
# Get single data
def get(self, request, pk):
book_obj = Book.objects.get(pk=pk)
serialized_data = BookSerializer(book_obj, many=False)
return Response(serialized_data.data)
First optimization: optimize interface logic with mixin
from django.urls import re_path
urlpatterns = [
re_path(r'books/$', views.BookView.as_view()),
re_path(r'books/(?P<pk>\d+)/$', views.BookFilterView.as_view()),
]
# -*- coding: utf-8 -*-
from rest_framework.mixins import (
ListModelMixin,
CreateModelMixin,
UpdateModelMixin,
DestroyModelMixin,
RetrieveModelMixin
)
from rest_framework.generics import GenericAPIView
# Modules in the current app
from .models import Book
from mixin_serializer import BookSerializer
# Create your views here.
class BookView(ListModelMixin, CreateModelMixin, GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class BookFilterView(DestroyModelMixin,
UpdateModelMixin,
RetrieveModelMixin,
GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
- DRF defines these five interfaces in different modelmixins. The steps are as follows:
- Import ModelMixin
- ModelMix required for view class inheritance
- Instead of inheriting APIView, you need to inherit generics.GenericAPIView
- There must be two class variables: queryset and serializer class
- There is no need to define any logical operation in the interface, and everything is handed to mixin
- The return values of each interface are different. The corresponding relationships are: {"get": "list", "delete": "destroy", "put": "update", "get": "retrieve", "post": "create"}
Second optimization: use view to optimize the interface logic
# -*- coding: utf-8 -*-
from rest_framework import generics
# Modules in the current app
from .models import Book
from .serializer_classes import BookSerializer
# Create your views here.
class BookView(generics.ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
class BookFilterView(generics.RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
The third Optimization: optimizing interface logic with viewset
from django.urls import re_path
urlpatterns = [
re_path(r'books/$', views.BookView.as_view({
'get': 'list',
'post': 'create'
})),
re_path(r'books/(?P<pk>\d+)/$', views.BookView.as_view({
'get': 'retrieve',
'put': 'update',
'delete': 'destroy'
})),
]
# -*- coding: utf-8 -*-
# django rest framework component
from rest_framework.viewsets import ModelViewSet
# Modules in the current app
from .models import Book
from .serializer_classes import BookSerializer
# Create your views here.
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer