基於GenericAPIView以及五個檢視擴充套件類寫介面

2023-02-11 15:00:25

基於GenericAPIView以及五個檢視擴充套件類寫介面

​ 引言,本篇文章的研究主題是檢視類的由簡單寫法到高階寫法過程換句話說不斷繼承不斷封裝最終變成擴充套件性大的檢視類,這樣寫介面的選擇就多了,可以個性化寫出自己想寫的後端程式碼,雖然寫的程式碼看起來少但是很多活兒已經被被封裝的類幹完了,我們只需要匯入一下然後繼承一下最後自己屬性或方法來實現,當然只是不能是一蹴而就的,過程才是最享受的,因為當我們知道這個知識點怎麼來的時候,我們對該知識印象更深。而且有必要的時候可以玩兒出很多花樣。所以過程遠比結果重要。好啦,話不多說直接上乾貨!!! GenericAPIView繼承了繼承了APIView,從而有很多新的屬性和方法,寫介面之後的效果是一樣的但是程式碼的可用性變高了,變得更加通用的。使用該類之前先了解一下它的屬性和方法吧

一、基於GenericAPIView寫介面

GenericAPIView屬性

  1. 序列化反序列 queryset
  2. 使用序列化類 serializer_class
  3. 查詢單條路由 lookup_field
  4. 過濾類的設定 filter_backends
  5. 分頁類的設定 pagination_class

GenericAPIView方法

  1. 獲取序列物件 get_queryset
  2. 獲取單個物件 get_object
  3. 獲取序列化類 get_serializer
  4. 跟過濾有關的 filter_queryset
# 表模型程式碼
from django.db import models


class Book(models.Model):
    name = models.CharField(verbose_name='書名', max_length=32)
    price = models.CharField(verbose_name='價格', max_length=32)

    def __str__(self):
        return self.name

    # 外來鍵 書跟出版社是一對多
    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    # 外來鍵 書跟作者是多對多
    authors = models.ManyToManyField(to='Author')

    def publish_detail(self):
        return {'name': self.publish.name, 'address': self.publish.address}

    def author_list(self):
        list = []
        for author in self.authors.all():
            list.append({'name': author.name, 'phone': author.phone})
        return list


class Publish(models.Model):
    name = models.CharField(verbose_name='出版社名稱', max_length=32)
    address = models.CharField(verbose_name='出版社地址', max_length=32)

    def __str__(self):
        return self.name


class Author(models.Model):
    name = models.CharField(verbose_name='作者姓名', max_length=32)
    phone = models.CharField(verbose_name='電話號碼', max_length=11)

    def __str__(self):
        return self.name

# 序列化類程式碼
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        # 跟book表有強關聯
        model = Book
        # fields = ['寫需要序列化的欄位名',[]···]
        # 如果fields = '__all__'這樣寫就表明序列化所有欄位
        fields = '__all__'
        # extra_kwargs = {'欄位名': {'約束條件': 約束引數},是反序列化欄位
        extra_kwargs = {'name': {'max_length': 8},
                        'publish_detail': {'read_only': True},
                        'authors_list': {'read_only': True},
                        'publish': {'write_only': True},
                        'authors': {'write_only': True}
                        }

    def validate_name(self, name):
        if name.startswith('sb'):
            raise ValidationError('書名不能以sb開頭')
        else:
            return name


'''基於GenericAPIView'''
from rest_framework.generics import GenericAPIView
from .models import Book
from .serializer import BookSerializer
from rest_framework.response import Response


class BookView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request):
        objs = self.get_queryset()
        ser = self.serializer_class(instance=objs, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '新增成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})


class BookDetailView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request, pk):
        obj = self.get_object()
        ser = self.get_serializer(instance=obj)
        return Response(ser.data)

    def put(self, request, pk):
        obj = self.get_object()
        ser = self.get_serializer(instance=obj, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code':102, 'msg':'修改成功'})
        else:
            return Response({'code':103, 'msg':ser.errors})

    def delete(self, request, pk):
        self.get_object().delete()
        return Response({'code':104, 'msg':'刪除成功'})

二 、基於GenericAPIView以及五個檢視擴充套件類寫介面

首先捋一下五個檢視擴充套件類吧!切記這五個擴充套件類不能單獨使用,必須與GenericAPIView配合使用,需要寫哪種介面就用哪個擴充套件類即可。

  1. 新增資料,CreateModelMixin
  2. 修改資料,UpdateModelMixin
  3. 刪除資料,DestroyModelMixin
  4. 獲取單個,RetrieveModelMixin
  5. 獲取所有,ListModelMixin
'''基於GenericAPIView及五個檢視擴充套件類'''

from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin
from .models import Book, Author, Publish
from .serializer import BookSerializer



class BookView(GenericAPIView,ListModelMixin,CreateModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request):
        return self.list(request)

    def post(self, request):
        return self.create(request)


class BookDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    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)