zoukankan      html  css  js  c++  java
  • Django-Rest-Framework 教程: 3. 使用 class based views

    在上一篇Django-Rest-Framework 教程: 2. Requests 和 Responses中, 使用的是function based views. 在本篇中, 主要介绍怎样使用class based views.

    1. 修改views.py

    首先修改snippet_list view:

        # snippets/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):
            """
            展示所有存在的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)
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    使用class based view代替 snippet_list后, 两者的代码非常相似, 但对于不同Http动作, 分离效果更为优秀. 对于snippet_detail:

        # snippets/views.py
        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)

    更新urls.py:

        # snippets/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)

    class based view改造完成, 现在可以使用之前的测试方法进行测试了.

    2. 使用 Mixins

    使用class based views的一大好处是, 我们可以使用各种mixin.

    Django-rest-framework为我们提供了许多现成的mixins, 方便我们像使用model-backed API一样构建 “创建/获取/更新/删除” API. 我们试着使用Mixins改写原先的view.

    GenericAPIView为我们提供了view核心的功能, 而ListModelMixin和CreateModelMixin为我们提供了.list()和.create()功能. 我们将这些功能与http动作绑定:

        # snippets/views.py
        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)

    同样的, 我们使用GenericAPIView, RetrieveModelMixin, UpdateModelMixin和DestroyModelMixin改写views.py:

        # snippets/views.py
        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)

    3. 使用generic class based views

    同Django一样, django-rest-framework为我们提供了现成的generic class based views. 接下来我们使用这些GCBVs再一次修改原有的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

    可以发现, 使用GCBVs后, 代码变得的更为精简易懂.

    原文链接: http://www.weiguda.com/blog/21/

  • 相关阅读:
    第六节:流上下文
    第五节:控制序列化和反序列化的数据
    第四节:格式化器如何序列化类型实例
    第三节:控制序列化和反序列化
    第二节:使类型可序列化
    第一节:序列化和反序列化快速入门
    第五节:使用反射发现类型成员
    golang 一些坑 rang
    golang json格式字符串反序列化映射到切片结构体
    golang 结构体内嵌结构体序列化填充
  • 原文地址:https://www.cnblogs.com/leo23/p/5051911.html
Copyright © 2011-2022 走看看