• 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/

  • 相关阅读:
    hibernate核心配置
    h5的部分新元素或属性
    java编译优化
    java值和地址值传递、字符串常量池的理解
    实现两数交换的几种方法
    数据类型转换-运算符
    [LeetCode] 395. Longest Substring with At Least K Repeating Characters
    [LeetCode] 823. Binary Trees With Factors
    [LeetCode] 772. Basic Calculator III
    [LeetCode] 1404. Number of Steps to Reduce a Number in Binary Representation to One
  • 原文地址:https://www.cnblogs.com/leo23/p/5051911.html
Copyright © 2020-2023  润新知