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/,测试结果