django-rest-framework学习之路-4-基于类的视图


1、基于类的视图

之前我们都是基于函数写的视图,接下来我们学习一下基于类的视图

重写snippets/views.py

from django.http import Http404
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer


class SnippetList(APIView):
    """
    列出所有的snippets或者创建一个新的snippet。
    """

    def get(self, request, format=None):
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = SnippetSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class SnippetDetail(APIView):
    """
    检索,更新或删除一个snippet示例。
    """

    def get_object(self, pk):
        try:
            return Snippet.objects.get(pk=pk)
        except Snippet.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = SnippetSerializer(snippet)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = SnippetSerializer(snippet, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

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

更新snippets/urls.py路由

urlpatterns = [
    re_path(r'^snippets_list/$', views.SnippetList.as_view()),
    re_path(r'^snippets_detail/(?P[0-9]+)/$', views.SnippetDetail.as_view()),
]

如果你启动服务,那么它应该像之前一样可以运行。请注意已经改了路径了,需要使用新的路径

http://127.0.0.1:8000/snippets/snippets_detail/1/

http://127.0.0.1:8000/snippets/snippets_list/

2、使用混合mixins类

之前我们基于类视图的实现,都是继承APIView类,基于类视图的最大优势之一是它可以轻松地创建可复用的行为。

接下啦我们引入一些新的类

ListModelMixin类:列出一个结果集

CreateModelMixin类:创建一个模型实例

GenericAPIView类:通用视图的基类

RetrieveModelMixin:检索出一个模型实例

UpdateModelMixin:更新一个模型实例

DestroyModelMixin:删除一个模型实例

  • 又一次重写snippets/views.py
from rest_framework import generics
from rest_framework import mixins

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer


class SnippetList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

    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 SnippetDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

    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)

我们将花点时间好好看下这里的具体实现方式。我们使用GenericAPIView构建了我们的视图,并且用上了ListModelMixin和CreateModelMixin。

基类提供核心功能,而mixin类提供.list()和.create()操作。然后我们明确地将get和post方法绑定到适当的操作。都目前为止都是显而易见的。

非常相似。这一次我们使用GenericAPIView类来提供核心功能,并添加mixins来提供.retrieve()),.update()和.destroy()操作。

如果你启动服务,那么它应该像之前一样可以运行。

  • http://127.0.0.1:8000/snippets/snippets_list/

  • http://127.0.0.1:8000/snippets/snippets_detail/1/

这次给我的感觉,很明显就是前端添加了HTML from表单,非常的人性化,相对于继承APIView类的实现

3、使用通用的基于类的视图

通过使用mixin类,我们使用更少的代码重写了这些视图,但我们还可以再进一步。REST框架提供了一组已经混合好(mixed-in)的通用视图,我们可以使用它来简化我们的views.py模块。

又一次重写snippets/views.py

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import generics


class SnippetList(generics.ListCreateAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer


class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

如果你启动服务,那么它应该像之前一样可以运行。

哇,如此简洁。我们可以使用很多现成的代码,让我们的代码看起来非常清晰、简洁,地道的Django。

学习链接:https://www.w3cschool.cn/lxraw/lxraw-ynl435od.html