在最近這幾天,打算將 DRF 常用的 class 的功能以及使用方法,帶大家有一個基礎的認識,幫助大家能快速地上手。只要能把基礎的 class 以及功能熟悉,相信大家可以透過 DRF 快速地創造出後端應用。
DRF 重視 "DRY" 的概念 => "Don't Repeat Yourself"。因此將很多常用到的邏輯概念,編寫成元件供開發者使用,相信在介紹 Viewsets, Serializers 的時候大家都有感受到吧!
而 APIViews 也是在 DRF 中非常常使用到的 class。APIViews 建立了可以直接對應 HTTP Method 的view。再處理 HTTP 的Reuqest 是非常實用的工具。
這邊我們一起透過 APIView 實作處理 product 請求的功能:
views.py
from rest_framework.views import APIView
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response
from rest_framework import status
from .models import Product
from .serializers import ProductSerializer
class ProductAPIView(APIView):
def get_object(self, pk):
product = get_object_or_404(Product, pk=pk)
return product
def get(self, request, pk):
product = self.get_object(pk)
serializer = ProductSerializer(peoduct)
return Response(serializer.data)
def put(self, request, pk):
product = self.get_object(pk)
serializer = ProductSerializer(product, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk):
product = self.get_object(pk)
product.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
urls.py
from django.urls import path
from .views import ProductAPIView
urlpatterns = [
path("product/<int:pk>/", ProductAPIView.as_view(), name="product"),
]
ProductAPIView 繼承了 APIView ,當Request 從url 進入傳到 views 的 function時, APIView 可以直接對應 HTTP Reuest 中的 GET, PUT, DELETE 的 Method 並執行相應動作。
APIView 也可以使用裝飾器 "@" 的寫法。在function之前加入 @APIView 使 HTTP Request 可以對應到相對的 function
@api_view(["GET", "PUT", "DELETE"])
def product_api_view(request, pk):
product = Product.objects.get(pk=pk)
if request.method == "GET":
serializer = ProductSerializer(product)
return Response(serializer.data)
elif request.method == "PUT":
serializer = ProductSerializer(product, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == "DELETE":
product.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
urls.py
from django.urls import path
from news.api.views import product_api_view
urlpatterns = [
path("products/<int:pk>/", product_api_view, name="product")
]
url 接收到 Reuqest ,送到 api_view ,而apiview幫忙分辨 Request 的 Method 並讓unction 可以進行盼隊且執行相對的功能。
今天我們又學習到一個強大且實用的利器 -- APIView。透過 APIView 可以幫助大家在處理 HTTP Method 時可以很有效率的寫出可讀性高的代碼!