Django基礎之(十一)DRF不一樣版本的視圖集演變

視圖集

簡介

  • REST框架包括一個用於處理ViewSets的抽象,它容許開發人員集中精力對API的狀態和交互進行建模,並根據常規約定自動處理URL構造。
  • ViewSet類與View類幾乎相同,不一樣之處在於它們提供諸如read或update之類的操做,而不是get或put等方法處理程序
  • ViewSet類只綁定到一組方法處理程序,當它被實例化成一組視圖的時候,一般經過使用一個Router類來處理本身定義URL conf的複雜性。

路由器

由於咱們使用的是ViewSet類而不是View類,咱們實際上不須要本身設計URL。將資源鏈接到視圖和url的約定可使用Router類自動處理。咱們須要作的就是使用路由器註冊相應的視圖集,而後讓它執行其他操做。

視圖vs視圖集之間的權衡

  • 使用視圖集能夠是一個很是有用的抽象。它有助於確保URL約定在你的API中保持一致,最大限度地減小編寫所需的代碼量,讓你可以專一於API提供的交互和表示,而不是URLconf的細節。
  • 這並不意味着採用視圖集老是正確的方法。在使用基於類的視圖而不是基於函數的視圖時,有一個相似的權衡要考慮。使用視圖集不像單獨構建視圖那樣明確。

不一樣的版本演練

版本一

  • idc/urls.py
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'idcs/$',views.idc_list),
    url(r'idcs/(?P<pk>[0-9]+)/$',views.idc_detail),
]
  • models.py
from django.db import models
# Create your models here.
class Idc(models.Model):
    name = models.CharField("IDC名稱",max_length=128,blank=False,null=True)
    address = models.CharField("IDC地址",max_length=200,default="")
    phone = models.CharField("IDC聯繫電話",max_length=20,null=True)
    email = models.EmailField("IDC郵箱")

    def __str__(self):
        return self.name

    class Meta:
        db_table = "idc"
  • serializers.py
from rest_framework import serializers
from .models import Idc

class IdcSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField(required=False)
    address = serializers.CharField(required=False)
    phone = serializers.CharField(required=False)
    email = serializers.EmailField(required=False)

    def update(self, instance, validated_data):
        instance.name = validated_data.get("name",instance.name)
        instance.address = validated_data.get("address",instance.address)
        instance.phone = validated_data.get("phone",instance.phone)
        instance.email = validated_data.get("email",instance.email)
        instance.save()
        return instance

    def create(self, validated_data):
        return Idc.objects.create(**validated_data)
  • views.py
from .models import Idc
from .serializers import IdcSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from django.http import HttpResponse,JsonResponse

class JSONResponse(HttpResponse):
    def __init__(self,data,**kwargs):
        kwargs.setdefault('content_type', 'application/json')
        content = JSONRenderer().render(data)
        super(JSONResponse,self).__init__(content=content,**kwargs)

def idc_list(request,*args,**kwargs):
    if request.method == "GET":
        queryset = Idc.objects.all()
        serializer = IdcSerializer(queryset,many=True)
        return JSONResponse(serializer.data)
        # content = JSONRenderer().render(serializer.data)
        # return HttpResponse(content,content_type="application/json")

    elif request.method == "POST":
        content = JSONParser().parse(request)
        serializer = IdcSerializer(data=content)
        if serializer.is_valid():
            serializer.save()
            content = JSONRenderer().render(serializer.data)
            return HttpResponse(content, content_type="application/json")

def idc_detail(request,pk,*args,**kwargs):
    try:
        idc = Idc.objects.get(pk=pk)
    except Idc.DoesNotExist:
        return HttpResponse(status=404)

    if request.method == "GET":
        serializer = IdcSerializer(idc)
        return JSONResponse(serializer.data)

    elif request.method == "POST":
        content = JSONParser().parse(request)
        serializer = IdcSerializer(data=content)
        if serializer.is_valid():
            serializer.save()
            return JSONResponse(serializer.data)

    elif request.method == "PUT":
        content = JSONParser().parse(request)
        serializer = IdcSerializer(idc,data=content)    #這裏要注意傳入instance(idc)不然就是建立操做
        if serializer.is_valid():
            serializer.save()
            return JSONResponse(serializer.data)

    elif request.method == "DELETE":
        idc.delete()
        return HttpResponse(status=204)

版本二

基於rest_framework下的:Response方法,status定義和api_view裝飾器django

  • idc/urls.py
## 版本二
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
    url(r'^$',views.api_root),
    url(r'idcs/$',views.idc_list_v2,name="idc-list"),
    url(r'idcs/(?P<pk>[0-9]+)/$',views.idc_detail_v2,name='idc-detail'),
]
urlpatterns=format_suffix_patterns(urlpatterns)
  • idc/views.py
### 版本二
from rest_framework.response import Response
from rest_framework import status
from rest_framework.decorators import api_view

@api_view(['GET','POST'])
def idc_list_v2(request,*args,**kwargs):
    if request.method == "GET":
        queryset = Idc.objects.all()
        serializer = IdcSerializer(queryset,many=True)
        return Response(serializer.data)

    elif request.method == "POST":
        content = JSONParser().parse(request)
        serializer = IdcSerializer(data=content)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data,status=status.HTTP_201_CREATED)
        return Response(serializer.data,status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET','POST','PUT','DELETE'])
def idc_detail_v2(request,pk,*args,**kwargs):
    try:
        idc = Idc.objects.get(pk=pk)
    except Idc.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == "GET":
        serializer = IdcSerializer(idc)
        return Response(serializer.data)

    elif request.method == "POST":
        content = JSONParser().parse(request)
        serializer = IdcSerializer(data=content)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)

    elif request.method == "PUT":
        content = JSONParser().parse(request)
        serializer = IdcSerializer(idc,data=content)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)

    elif request.method == "DELETE":
        idc.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

from rest_framework.reverse import reverse
@api_view(['GET'])
def api_root(request,format=None,*args,**kwargs):
    return Response({
        "idcs":reverse("idc-list",request=request,format=format)
    })
  • 測試:

瀏覽器打開:http://192.168.33.10:8080/idcs/ 便可json

版本三

基於類視圖的版本,要注意接受提交數據用的是request.dataapi

  • idc/urls.py
###版本三
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
    url(r'^$',views.api_root),
    url(r'idcs/$',views.IdcListView.as_view,name="idc-list"),
    url(r'idcs/(?P<pk>[0-9]+)/$',views.IdcDetailView.as_view,name='idc-detail'),
]
urlpatterns=format_suffix_patterns(urlpatterns)
  • idc/views.py
### 版本三
from rest_framework.views import APIView
from django.http import Http404

class IdcListView(APIView):
    def get(self,request,format=None):
        queryset = Idc.objects.all()
        serializer = IdcSerializer(queryset, many=True)
        return Response(serializer.data)

    def post(self,request,format=None):
        #content = JSONParser().parse(request)
        serializer = IdcSerializer(data=request.data) #request.data獲取請求參數
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.data, status=status.HTTP_400_BAD_REQUEST)

class IdcDetailView(APIView):
    def get_obj(self,pk):
        try:
            return Idc.objects.get(pk=pk)
        except Idc.DoesNotExist:
            raise Http404

    def get(self,request,pk,format=None):
        idc = self.get_obj(pk)
        serializer = IdcSerializer(idc)
        return Response(serializer.data)

    def put(self,request,pk,format=None):
        idc = self.get_obj(pk)
        serializer = IdcSerializer(idc,data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.data,status=status.HTTP_400_BAD_REQUEST)

    def delete(self,request,pk,format=None):
        idc = self.get_obj(pk)
        idc.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

版本四

  • idc/urls.py
###版本四
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
    url(r'^$',views.api_root),
    url(r'idcs/$',views.IdcList_V4.as_view(),name="idc-list"),
    url(r'idcs/(?P<pk>[0-9]+)/$',views.IdcDetail_V4.as_view(),name='idc-detail'),
]
urlpatterns=format_suffix_patterns(urlpatterns)
  • views.py
###版本四
from rest_framework import mixins,generics

class IdcList_V4(generics.GenericAPIView,
                 mixins.ListModelMixin,
                 mixins.CreateModelMixin):
    queryset = Idc.objects.all()
    serializer_class = IdcSerializer

    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 IdcDetail_V4(generics.GenericAPIView,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin):
    queryset = Idc.objects.all()
    serializer_class = IdcSerializer
    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,*args,**kwargs)

版本五

  • urls.py
###版本五
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
    url(r'^$',views.api_root),
    url(r'idcs/$',views.IdcList_V5.as_view(),name="idc-list"),
    url(r'idcs/(?P<pk>[0-9]+)/$',views.IdcDetail_V5.as_view(),name='idc-detail'),
]
urlpatterns=format_suffix_patterns(urlpatterns)
  • views.py
### 版本五
class IdcList_V5(generics.ListCreateAPIView):
    queryset = Idc.objects.all()
    serializer_class = IdcSerializer

class IdcDetail_V5(generics.RetrieveUpdateDestroyAPIView):
    queryset = Idc.objects.all()
    serializer_class = IdcSerializer

版本六

  • urls.py
## 版本六
idc_list = views.IdcViewSet.as_view({
    "get":"list",
    "post":"create"
})
idc_detail = views.IdcViewSet.as_view({
    "get":"retrieve",
    "put":"update",
    "delete":"destroy"
})
urlpatterns = [
    url(r'^$',views.api_root),
    url(r'idcs/$',idc_list,name="idc-list"),
    url(r'idcs/(?P<pk>[0-9]+)/$',idc_detail,name='idc-detail'),
]
urlpatterns=format_suffix_patterns(urlpatterns)
  • views.py
####版本六
from rest_framework import viewsets
class IdcViewSet(viewsets.GenericViewSet,
                 mixins.RetrieveModelMixin,
                 mixins.UpdateModelMixin,
                 mixins.DestroyModelMixin,
                 mixins.ListModelMixin,
                 mixins.CreateModelMixin):
    queryset = Idc.objects.all()
    serializer_class = IdcSerializer

版本七

  • urls.py
###版本七
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register("idcs",views.IdcViewSet_V7) #自動適配,字啊須要加的話就直接加
urlpatterns = [
    url(r'^',include(router.urls))
]
  • views.py
### 版本七
class IdcViewSet_V7(viewsets.ModelViewSet):
    queryset = Idc.objects.all()
    serializer_class = IdcSerializer
相關文章
相關標籤/搜索