欢迎来访我的博客。

Django Rest Framework学习总结-3:基于类的视图

Django 小张哥哥 239浏览 0评论

在前一篇文章中,我们使用的是基于函数的视图。我们同样可以写基于类的视图。写基于类的视图是一个更好的选择,可以提高我们代码的复用性。


使用基于类的视图重写API

现在我们将之前的基于函数的视图重写为基于类的视图。重新修改我们的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 .models import Snippet
from .serializers import SnippetSerializer


class SnippetList(APIView):
    """
    列出所有的snippet,或者创建一个新的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)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

代码与之前类似,只是根据不同的HTTP请求类型,将代码分开写道两个方法中。
然后,我们再继续更新views.py文件:

class SnippetDetail(APIView):
    """
    获取,更新或者删除snippet
    """
    def get_object(self, pk):
        try:
            snippet = Snippet.objects.get(pk=pk)
            return snippet        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)
        else:
            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文件:

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views

urlpatterns = [
    path('snippets/', views.SnippetList.as_view()),
    path('snippets/<int:pk>/', views.SnippetDetail.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)

我们可以试着运行server,运行起来之后,表现应该和之前的基于函数的视图是一样的。


使用mixins

基于类的视图有一个很重要的优点,我们可以很方便的复用一些行为很类似的代码。
创建/获取/更新/删除这几种操作对于任意的基于模型的API视图都是很相似的。这些相似的操作行为已经在REST framework中的mixin类中帮我们实现了。

现在我们来看一下如何通过使用这些mixin类来创建我们的视图函数。现在重写views.py文件如下:

from rest_framework.generics import GenericAPIView
from rest_framework import mixins
from .models import Snippet
from .serializers import SnippetSerializer


class SnippetList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  GenericAPIView):
    """
    列出所有的snippet,或者创建一个新的snippet
    """
    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)

我们现在来看看这里的代码。我们现在基于GenericAPIView来构建我们的视图,并加上了ListModelMixin和CreateModelMixin。
基类提供了主要的功能。mixin类提供了.list()和.create()方法。然后我们再给get和post方法绑定不同的操作行为。

class SnippetDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    GenericAPIView):
    """
    获取,更新或者删除snippet
    """
    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提供核心的功能项,然后mixin类提供了.retrieve(), .update()和.destory()方法。


使用通用类视图

使用mixin类,我们的代码已经重构的比之前的代码都少很多了,但是我们其实可以进一步简化。
REST framework提供了一系列已经整合好的通用的视图函数(mixed-in generic views)。我们可以用它来进一步减少我们的代码。

from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
from .models import Snippet
from .serializers import SnippetSerializer


class SnippetList(ListCreateAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializerclass SnippetDetail(RetrieveUpdateDestroyAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

现在我们的代码已经非常简洁了。



本文中的源码可以在Github上查看。点我查看本文源码



转载请注明:禅思 » Django Rest Framework学习总结-3:基于类的视图?

喜欢 (0) or 分享 (0)

我的个人微信公众号,欢迎关注

扫码或搜索:Python后端开发Django

Python后端开发Django

微信公众号 扫一扫关注

结交朋友、一起学习,一起进步。

科波之主

QQ号 386046154 立即加入

添加微信,进行技术交流

专注技术交流, 一同成长进步

我的微信号

如果您喜欢我的文章,感觉我的文章对您有帮助,请狠狠点击下面

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(0)个小伙伴在吐槽