1. 程式人生 > 實用技巧 >View與APIView的區別

View與APIView的區別

.-.-.https://www.cnblogs.com/yoyoketang/p/11523008.html

前言

  • django中編輯檢視views.py有兩種方式,一種是基於類的實現,另外一種是函式式的實現方式,兩種方法都可以用。
  • REST框架提供了一個APIView類,它是Django View類的子類。

\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\)

View與APIView的區別

View是Django預設的檢視基類APIView是REST framework提供的所有檢視的基類, 繼承自Django的View。

APIView與View的不同之處在於:

  • 傳入到檢視方法中的是REST framework的Request物件,而不是Django的HttpRequeset物件;
  • 檢視方法可以返回REST framework的Response物件,檢視會為響應資料設定(render)符合前端要求的格式;
  • 任何APIException異常都會被捕獲到,並且處理成合適的響應資訊;APIException異常捕獲
  • 在進行dispatch()分發前,會對請求進行身份認證、許可權檢查、流量控制。

\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\)

REST framework的APIView繼承了django的View

APIView多了一些屬性和方法,比如:身份認證、許可權檢查、流量控制

  • authentication_classes 身份認證
  • permission_classes 許可權檢查
  • throttle_classes 流量控制

APIView的序列化也比View的序列化好用一些 但是報錯不好找 具體使用哪個個人斟酌

先使用django自帶的view,獲取一個Card表裡面的卡號資訊:
models.py設計card表

\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\)

# models.py
class Card(models.Model):
    '''銀行卡 基本資訊 
    card_id = models.CharField(max_length=30, verbose_name="卡號", default="")
    card_user = models.CharField(max_length=10, verbose_name="姓名", default="")
    add_time = models.DateField(auto_now=True, verbose_name="新增時間")

    class Meta:
        verbose_name_plural = '銀行卡賬戶'
        verbose_name = "銀行卡賬戶_基本資訊"
        
    def __str__(self):
        return self.card_id

\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\)

views.py檢視的編寫

from django.http import JsonResponse
from rest_framework import serializers
from django.core import serializers as dj_serializers  # 避免和rest_framework裡面的serializers衝突
from .models import *
from django.views.generic.base import View
import json


class CardListView(View):
    '''基於django的view實現獲取card列表'''
    def get(self, request):
        data = {}
        cards = Card.objects.all()
        data['result'] = json.loads(dj_serializers.serialize("json", cards))
        return JsonResponse(data)		
from django.http import HttpResponse
from django.views import View

class Test1View(View):
    def get(self, request):
        data = request.GET.get('name')  # View獲取前端傳遞的GET請求name引數
        return HttpResponse(data)

    def post(self, request):
        data = request.POST.get('username')  # View獲取前端傳遞的POST請求username引數
        return HttpResponse(data)

\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\)

urls.py設定訪問地址

from apiapp import views
from django.conf.urls import url

urlpatterns = [
    url(r'^api/v1/cards/$', views.CardListView.as_view()),

]

\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\)

REST framework的APIView

\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\)

REST framework的APIView繼承了django的View類,先序列化Card類,這裡的序列化用rest_framework裡面的ModelSerializer

from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import serializers
from .models import *
from rest_framework.permissions import IsAuthenticated,AllowAny
from rest_framework.authentication import TokenAuthentication


class CardAPISerializer(serializers.ModelSerializer):   # 繼承自ModelSerializer類
    '''序列化資料的類,根據model表來獲取欄位'''
    class Meta:
        model = Card
        fields = '__all__'


class CardListAPIView(APIView):
    '''REST framework的APIView實現獲取card列表'''
    # authentication_classes = (TokenAuthentication,)  # token認證
    # permission_classes = (IsAuthenticated,)   # IsAuthenticated 僅通過認證的使用者
    permission_classes = (AllowAny,)  # 允許所有使用者

    def get(self, request, format=None):
        """
        Return a list of all users.
        """
        cards = Card.objects.all()
        serializer = CardAPISerializer(cards, many=True)
        return Response(serializer.data)

\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\)

from rest_framework.views import APIView
from rest_framework.response import Response


class TestView(APIView):
    def get(self, request):
        data = request.query_params  # APIView獲取前端傳遞的GET請求引數
        # data = request.GET.get('name')
        # 使用View獲取前端傳遞的GET請求引數 因為APIView繼承和封裝了View 
        # 所以View獲取GET請求的方式APIView也可以使用
        return Response(data)

    def post(self, request):
        # data = request.data.get('username')
        data = request.POST.get('username')
        # 使用View獲取前端傳遞的POST請求引數 因為APIView繼承和封裝了View 
        # 所以View獲取POST請求的方式APIView也可以使用
        return Response({'username': data})

\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\)

配置urls.py,設定訪問地址

from apiapp import views
from django.conf.urls import url

urlpatterns = [
    url(r'^api/v1/cardlist/$', views.CardListAPIView.as_view()),

]