python測試開發django-62.基於類的視圖(APIView和View)

  • 2019 年 10 月 4 日
  • 筆記

前言

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

View與APIView的區別

View是Django默認的視圖基類,APIView是REST framework提供的所有視圖的基類, 繼承自Django的View

APIViewView的不同之處在於:

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

django的View部分源碼

class View:      """      Intentionally simple parent class for all views. Only implements      dispatch-by-method and simple sanity checking.      """        http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']        def __init__(self, **kwargs):          """          Constructor. Called in the URLconf; can contain helpful extra          keyword arguments, and other things.          """          # Go through keyword arguments, and either save their values to our          # instance, or raise an error.          for key, value in kwargs.items():              setattr(self, key, value)

REST framework的APIView繼承了django的View,部分源碼如下

class APIView(View):        # The following policies may be set at either globally, or per-view.      renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES      parser_classes = api_settings.DEFAULT_PARSER_CLASSES      authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES      throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES      permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES      content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS      metadata_class = api_settings.DEFAULT_METADATA_CLASS      versioning_class = api_settings.DEFAULT_VERSIONING_CLASS        # Allow dependency injection of other settings to make testing easier.      settings = api_settings        schema = DefaultSchema()

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

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

django的View

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

# models.py  class Card(models.Model):      '''銀行卡 基本信息 # 作者:上海悠悠,QQ交流群:750815713'''      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  # 作者:上海悠悠,QQ交流群:750815713    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)

urls.py設置訪問地址

from apiapp import views  from django.conf.urls import url  # 作者:上海悠悠,QQ交流群:750815713    urlpatterns = [      url(r'^api/v1/cards/$', views.CardListView.as_view()),    ]

訪問http://127.0.0.1:8000/api/v1/cards/,測試結果

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  # 作者:上海悠悠,QQ交流群:750815713    class CardAPISerializer(serializers.ModelSerializer):   # 繼承自ModelSerializer類      '''序列化數據的類,根據model表來獲取字段'''      class Meta:          model = Card          fields = '__all__'    class CardListAPIView(APIView):      '''REST framework的APIView實現獲取card列表 # 作者:上海悠悠,QQ交流群:750815713'''      # 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)

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

from apiapp import views  from django.conf.urls import url  # 作者:上海悠悠,QQ交流群:750815713    urlpatterns = [      url(r'^api/v1/cardlist/$', views.CardListAPIView.as_view()),    ]

訪問http://127.0.0.1:8000/api/v1/cardlist/,測試結果