• 3,基于类的视图函数


    We can also write our API views using class based views, rather than function based views. As we'll see this is a powerful pattern that allows us to reuse common functionality, and helps us keep our code DRY.

    我们可以基于类来写 API 的视图函数,而不是基于函数。基于类的视图函数是一个有用的模式,它允许我们重用一些常用的功能,而且帮助我们减少代码的重覆。

    Rewriting our API using class based views

    基于类重写 API 视图函数

    We'll start by rewriting the root view as a class based view. All this involves is a little bit of refactoring of views.py.

    基于类的视图函数,只需要重构 views.py:

    from snippets.models import Snippet
    from snippets.serializers import SnippetSerializer
    from django.http import Http404
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework import status
    
    
    class SnippetList(APIView):
        """
        List all snippets, or create a new 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)

     So far, so good. It looks pretty similar to the previous case, but we've got better separation between the different HTTP methods. We'll also need to update the instance view in views.py.

    它看起来有点类似之前的,但是我们却很好的隔开了不同的HTTP方法。我们同样需要更新单个实例的视图函数,在views.py中添加如下代码:

    class SnippetDetail(APIView):
        """
        Retrieve, update or delete a snippet instance.
        """
        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)

    That's looking good. Again, it's still pretty similar to the function based view right now.

    We'll also need to refactor our urls.py slightly now we're using class based views.

    我们还需要稍微重构一下 urls.py

    from django.conf.urls import patterns, url
    from rest_framework.urlpatterns import format_suffix_patterns
    from snippets import views
    
    urlpatterns = patterns('',
        url(r'^snippets/$', views.SnippetList.as_view()),
        url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
    )
    
    urlpatterns = format_suffix_patterns(urlpatterns)

     Okay, we're done. If you run the development server everything should be working just as before.

    好了,打开服务器就可以看到与前一章同样的内容了。

    Using mixins

    使用mixins

    One of the big wins of using class based views is that it allows us to easily compose reusable bits of behaviour.

    The create/retrieve/update/delete operations that we've been using so far are going to be pretty similar for any model-backed API views we create. Those bits of common behaviour are implemented in REST framework's mixin classes.

    Let's take a look at how we can compose the views by using the mixin classes. Here's our views.py module again.

    使用基于类的视图最大的好处就是它可以允许我们很方便的组合一些可重用的方法。

    创建/检索/更新/删除 的方法通过REST框架中的 mixin 类实现

    from snippets.models import Snippet
    from snippets.serializers import SnippetSerializer
    from rest_framework import mixins
    from rest_framework import generics
    
    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)

    We'll take a moment to examine exactly what's happening here. We're building our view using GenericAPIView, and adding in ListModelMixin and CreateModelMixin.The base class provides the core functionality, and the mixin classes provide the .list() and .create() actions. We're then explicitly binding the get and post methods to the appropriate actions. Simple enough stuff so far.

    我们将会准确测试这些代码究竟发生了什么。我们用GenericAPIView建立我们的视图函数,在其中添加 ListModelMixin 和 CreateModelMixin。

    基类提供核心功能,mixin类提供.list()和.create()方法。然后我们显示地绑定 get 和 post 方法,

    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)

     Pretty similar. Again we're using the GenericAPIView class to provide the core functionality, and adding in mixins to provide the .retrieve(), .update() and .destroy() actions.

    如此相似,同样我们使用类 GenericAPIView 来提供核心功能,在其中加入 minxins 来提供 .retrieve(), update()和.destroy()方法。

    Using generic class based views

    使用基于泛型类的视图函数

    Using the mixin classes we've rewritten the views to use slightly less code than before, but we can go one step further. REST framework provides a set of already mixed-in generic views that we can use to trim down our views.py module even more.

    在上面,我们使用 mixin 类,通过少量的代码重写了视图函数。但是,我们还能更进一步, REST 框架提供了一些泛型类视图,我们可以用其再一次修剪 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

     Wow, that's pretty concise. We've gotten a huge amount for free, and our code looks like good, clean, idiomatic Django.

    Next we'll move onto part 4 of the tutorial, where we'll take a look at how we can deal with authentication and permissions for our API.

    现在,已经非常简明了,我们减少了很多代码量,看起来像干净利落的Django了。

    接下来,我们将去第四部分,看看如何处理认证和权限。

  • 相关阅读:
    设计模式之开篇(C#语法) 爱拼才会赢
    C#语法糖之第一篇:自动属性&隐式类型 爱拼才会赢
    C#语法糖之第四篇: 扩展方法 爱拼才会赢
    C#中this在扩展方法的应用
    笔记20120215_转义字符_运算符
    Linux基本操作
    SQL创表
    软件测试的概念
    java 线程池
    Redis广播
  • 原文地址:https://www.cnblogs.com/nigang/p/3755330.html
Copyright © 2020-2023  润新知