您的位置:

深入了解Django REST framework中的APIView

介绍

Django是最流行的Python Web框架之一,它提供了方便的开发开发Web应用程序的工具和框架。Django REST framework(简称DRF)是用于构建API的强大框架,它提供了各种视图类(View),其中最常用的是APIView。APIView是一个基于类的视图,允许我们使用Python面向对象编程来快速而灵活地构建API视图。

一、APIView的基础认识

APIView是DRF API视图的基础类。一个APIView和Django中的View非常相似。可以理解为是从视图函数TableView类中派生出来的一个新类。 APIView类使用的设计模式是模板方法模式。因此,APIView类定义了模板方法(如get()、post()等),以及其他辅助方法来显示DRF API视图的相关功能。

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

class HelloApiView(APIView):
    """Test API View."""

    def get(self, request, format=None):
        """Return a list of APIView features."""

        an_apiview = [
            'Uses HTTP methods as function (get, post, put, patch, delete)',
            'Is similar to a traditional Django view',
            'Gives you the most control over your logic',
            'Is mapped manually to URLs'
        ]

        return Response({'message': 'Hello!', 'an_apiview': an_apiview})

二、APIView的RESTful API特性

像Django和其他RESTful框架,DRF APIView支持RESTful API。 RESTful API的概念来源于REST风格的网络服务。

利用APIView,我们可以将DRF视图细化到资源API中的单个方法或操作。这意味着在APIView中可以使用五个常用的HTTP方法:GET,POST,PUT,PATCH和DELETE。每个方法自己对资源列表(集合)或单个资源进行操作,包括:获取、创建、更新和删除。

当然,确保使用DRF需要导入DRF模块,并从APIView扩展。

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

class HelloApiView(APIView):
    """Test API View."""

    def get(self, request, format=None):
        """Return a list of APIView features."""

        an_apiview = [
            'Uses HTTP methods as function (get, post, put, patch, delete)',
            'Is similar to a traditional Django view',
            'Gives you the most control over your logic',
            'Is mapped manually to URLs'
        ]

        return Response({'message': 'Hello!', 'an_apiview': an_apiview})

    def post(self, request):
        """Create a hello message with our name."""

        serializer = self.serializer_class(data=request.data)

        if serializer.is_valid():
            name = serializer.validated_data.get('name')
            message = f'Hello {name}!'
            return Response({'message': message})
        else:
            return Response(serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)

三、APIView的验证方式

作为一个开发者,我们需要保证安全性并且禁止可能的恶意行为。在DRF框架中,这是通过设置不同的许可证类来实现的: allowany,apiviewer,apiview allowany, apiview AllowAny等。这些许可证类确定API的访问权限,防止未经授权的访问。

allowany

Any用户是最基本的许可类。只要请求有效,API的任何部分都可以通过这个许可类得到访问权限。

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

class HelloView(APIView):

    permission_classes = (AllowAny,)

    def get(self, request, format=None):
        return Response({'Hello, World!'})

apiviewer

通过这个许可证类,我们需要一个具有基本身份验证的用户才能访问API的特定部分。

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

class HelloView(APIView):

    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):
        return Response({'Hello, World!'})

apiview AllowAny

这种许可证防止HTTP BASIC验证错误锁定APIs。

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import AllowAny

class AuthenticatedView(APIView):

    authentication_classes = [BasicAuthentication]
    permission_classes = [AllowAny]

    def get(self, request, format=None):
        return Response({'message': 'Success!'})

四、APIView和View的区别

除了APIView之外,Django【rest-framework】还提供了其他几种视图类(View Class),其中之一就是View类。ViewSet是一个在APIView和View之间的类。

尽管APIView类和View类(通常称为function-based views)提供了相同的功能,但使用APIView类会更容易。这是因为仅使用APIView类,我们可以使所有方法的逻辑分布在一个小的代码单元中。同时,APIView也让我们更清晰地组织代码、减少Bug、保护我们的代码并改进重用性。总之,APIView类是View的升级版。

五、APIView和ViewSet区别

APIView和ViewSet经常被同时使用。但是,ViewSet在APIView之上具有两个主要优点:

  • ViewSet提供了更好的代码重用性
  • ViewSet可以将模型与视图类结合在一起,而APIView不行

使用视图集ViewSet,我们可以在一个视图类中使用多种请求方法,并将它们关联到一个具体的模型。例如,我们可以像这样创建一个视图集:

from rest_framework import viewsets

class ArticleViewSet(viewsets.ModelViewSet):
    serializer_class = ArticleSerializer
    queryset = Article.objects.all()

从代码片段中,可以看出ViewSet比APIView更灵活、更易于编写和快速调整代码。另外,ViewSet强制使用诸如get、post、put、patch和delete等HTTP方法的设计模式。视图可轻松地解决不同的请求类型和代码操作,并通过DRF进行错误处理。