DRF的序列化組件

rest

rest下的urldjango

url惟一表明資源,http請求方式來區分用戶行爲編程

url的設計規範json

GET: 127.0.0.1:9001/books/        # 獲取全部數據session

GET: 127.0.0.1:9001/books/{id}      # 獲取單條數據app

POST: 127.0.0.1:9001/books/      # 增長數據ide

DELETE: 127.0.0.1:9001/books/{id}    # 刪除數據模塊化

PUT: 127.0.0.1:9001/books/{id}      # 修改數據post

數據響應規範優化

GET: 127.0.0.1:9001/books/        # 返回[{}, {}, {}]url

GET: 127.0.0.1:9001/books/{id}      # {} 單條數據

POST: 127.0.0.1:9001/books/        # {} 添加成功的數據

DELETE: 127.0.0.1:9001/books/{id}    # "" 返回空

PUT: 127.0.0.1:9001/books/{id}      # {} 更新後完整的數據

錯誤處理

{ "error": "message" }

解析器組件

  • 解析器組件是用來解析用戶請求的數據的(application/json), content-type

  • 必須繼承APIView

  • request.data觸發解析

APIView的使用

rest_framework是一個app須要在settings裏設置

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',  
]

pip install djangorestframework

from rest_framework.views import APIView

class LoginView(APIView):
def get(self, request):
pass

序列化組件

Django自帶的serializer

from django.serializers import serialize  # 引入
​
origin_data = Book.objects.all()
serialized_data = serialize("json", origin_data)

DRF的序列化組件

接口設計

from rest_framework import serializers  #引入

建立一個序列化類

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        # model字段
        fields = ('title',
                  'price',
                  'publish',
                  'authors',
                  'author_list',
                  'publish_name',
                  'publish_city'
                  )
        # 只需寫入不須要展現的字段
        extra_kwargs = {
            'publish': {'write_only': True},
            'authors': {'write_only': True}
        }
    # source爲自定義須要展現的信息
    publish_name = serializers.CharField(max_length=32, read_only=True, source='publish.name')
    publish_city = serializers.CharField(max_length=32, read_only=True, source='publish.city')
    # 多對多字段須要本身手動獲取數據,SerializerMethodField()
    author_list = serializers.SerializerMethodField()
​
    def get_author_list(self, book_obj):
        # 拿到queryset開始循環 [{}, {}, {}, {}]
        authors = list()
​
        for author in book_obj.authors.all():
            authors.append(author.name)
​
        return authors
建立序列化類

開始序列化

get接口(查詢多條數據) & post接口

class BookView(APIView):
    def get(self, request):
        # 獲取queryset
        origin_data = Book.objects.all()
        # 開始序列化
        serialized_data = BookSerializer(origin_data, many=True)
        return Response(serialized_data.data)
    def post(self, request):
        verified_data = BookSerializer(data=request.data)
        if verified_data.is_valid():
            book = verified_data.save()
            authors = Author.objects.filter(nid__in=request.data['authors'])
            book.authors.add(*authors)
            return Response(verified_data.data)
        else:
            return Response(verified_data.errors)

get(查詢單條數據) & put接口 & delete接口

class BookFilterView(APIView):
    def get(self, request, nid):
        book_obj = Book.objects.get(pk=nid)
        serialized_data = BookSerializer(book_obj, many=False)
        return Response(serialized_data.data)
​
    def put(self, request, nid):
        book_obj = Book.objects.get(pk=nid)
        verified_data = BookSerializer(data=request.data, instance=book_obj)
        if verified_data.is_valid():
            verified_data.save()
            return Response(verified_data.data)
        else:
            return Response(verified_data.errors)
​
    def delete(self, request, nid):
        book_obj = Book.objects.get(pk=nid).delete()
        return Response()

缺點:

serializers.Serializer沒法插入數據,只能本身實現create字段太多,不能自動序列化

接口設計優化

使用視圖組件的mixin進行接口邏輯優化

導入mixin

from rest_framework.mixinx import (
                    ListModelMix,
                    CreateModelMixin,
                    DestroyModelMixin,
                    UpdateModelMixin,
                    RetrieveModelMixin
                )
from rest_framework.generics import GenericAPIView
​

定義序列化類

Class BookSerializer(serializers.ModelSerializer):
                  class Meta:
                      Book
                      fields = ()
                      ...如上

由於使用模塊化編程,建議將定義的序列化類放在單獨的模塊中,再在view.py中導入

from .app_serializers import BookSerializer

定義視圖類​

class BookView(ListModelMix, CreateModelMixin, GenericAPIView):
    # queryset和serializer_class是固定的寫法
    queryset = Book.objects.all()
    serializer_class = BookSerializer      
    def get():
        return self.list() # 查詢多條
            
    def post():
        return self.create()
                
class BookFilterView(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
​
    def get():
        return self.retrieve()  # 查詢單條
def delete():
        return self.destroy()
​
    def put():
        return self.update()

注意:

查詢單挑數據的url須要給查詢的id進行正則分組

re_path(r'books/(?P<pk>\d+)/$, views.BookFilterView.as_view())

使用視圖組件的view進行接口邏輯優化

導入模塊

from rest_framework import generics

視圖類​

class BookView(generics.ListCreateAPIView)
    queryset = Book.objects.all()
    serializer_class = BookSerializer   
class BookFilterView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

使用視圖組件的viewset進行接口邏輯優化

導入模塊

from rest_framework.viewsets import ModelViewSet

設計url

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',
    'delete': 'destroy',
    'put': 'update'
    }))

設計視圖類

class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
相關文章
相關標籤/搜索