相较于使用基于方法(function based)的视图,我们更加倾向使用基于类(class based)的视图。接下来,你将看到这是一个强大的模式,是我们能够重用公共的功能,并且,帮我们减少重复的造轮子。

我们现在开始了。首先,重写根视图(root view),变成基于类的视图。所涉及的,只是对 views.py 文件的一点重构。

一、使用基于 APIView 类的视图

from testapps.models import Testapp
from testapps.serializers import TestappSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

class TestappList(APIView):
"""
列出所有代码片段(testapps), 或者新建一个代码片段(testapp).
"""
    def get(self, request, format=None):
        testapps = Testapp.objects.all()
        serializer = TestappSerializer(testapps, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = TestappSerializer(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)

至此为止,一切顺利。看起来,跟基于方法的差别不大,但我们将各个 HTTP 请求方法之间,做了更好的分离。接着,我们将同样的更改我们,处理片段详细的视图,继续我们的  views.py  文件:

class TestappDetail(APIView):

"""
读取, 更新 or 删除一个代码片段(testapp)实例(instance).
"""
    def get_object(self, pk):
        try:
            return Testapp.objects.get(pk=pk)
        except Testapp.DoesNotExist:
            raise Http404

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

    def put(self, request, pk, format=None):
        testapp = self.get_object(pk)
        serializer = TestappSerializer(testapp, 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):
        testapp = self.get_object(pk)
        testapp.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

看起来不错。但还是跟基于方法的视图,差别不多。

我们也需要重构 urls.py文件,因为我们现在使用的是基于类的视图。

from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from testapp import views

urlpatterns = [
    url(r'^testapp/$', views.TestappList.as_view()),
    url(r'^testapp/(?P<pk>[0-9]+)/$', views.TestappDetail.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)

好,搞定。如果你跑起开发者服务器,应该跟之前的效果是一样的。

二、使用 Mixins 类的视图

使用类视图的一大好处是,我们可以很容易地,组成可重复使用的行为。

目前为止,我们所用的增删改查操作,在我们创建的,任何支持模型的视图里,都没有太大区别。这些通用的行为,在 REST framework的 Mixin类中,都已经实现了。

让我们看看,使用混合类,如何组建视图。下面同样是我们的 views.py 模块:

from testapp.models import Testapp
from testapp.serializers import Testapperializer
from rest_framework import mixins
from rest_framework import generics

class TestappList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = Testapp.objects.all()
    serializer_class = Testapperializer

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

    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() 和 .destroy() 行为。

三、使用 Generic 类的视图

使用混 Mixin 类重新视图,相比之前,我们减少了一些代码,但我们还可以更进一步。REST framework 提供了一套已经实现了 Mixin 类的 Generic 视图,我们可以使我们的 views.py 模块,更加瘦身!

from testapps.models import Testapp
from testapps.serializers import TestappSerializer
from rest_framework import generics

class TestappList(generics.ListCreateAPIView):
    queryset = Testapp.objects.all()
    serializer_class = TestappSerializer

class TestappDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Testapp.objects.all()
    serializer_class = TestappSerializer

这下够简洁了。代码看起来像是很厉害的,干净的,地道的 Django。

Django REST framework 中 3 种类视图的对比的更多相关文章

  1. Django REST framework 中文文档

    Django REST framework介绍 现在前后端分离的架构设计越来越流行,业界甚至出现了API优先的趋势. 显然API开发已经成为后端程序员的必备技能了,那作为Python程序员特别是把Dj ...

  2. DRF (Django REST framework) 中的视图类

    视图说明 1. 两个基类 1)APIView rest_framework.views.APIView APIView是REST framework提供的所有视图的基类,继承自Django的View父 ...

  3. Django REST framework中的版本控制

    1.REST framework版本控制的流程分析 1.1 determine_version方法的执行流程 首先,请求到达REST framework的CBV,执行CBV中的dispatch方法再次 ...

  4. Django rest framework(8)---- 视图和渲染器

    django rest framework 之视图 序列化器    PagerSerialiser from rest_framework import serializers from api im ...

  5. 在django restful framework中设置django model的property

    众所周知,在django的model中,可以某些字段设置@property和setter deleter getter,这样就可以在存入数据的时候进行一些操作,具体原理请参见廖雪峰大神的博客https ...

  6. JWT验证机制【刘新宇】【Django REST framework中使用JWT】

    JWT 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证.我们不再使用Session认证机制,而使用Json Web Token认证机制. 什么是JWT Json web t ...

  7. Django REST framework 中的视图

    1.Request REST framework传入视图的request对象不再是Django默认的Httprequest对象,而是DRF提供的扩展类的Request类的对象 常用属性 request ...

  8. DRF (Django REST framework) 中的视图扩展类

    2. 五个扩展类 1)ListModelMixin 列表视图扩展类,提供list(request, *args, **kwargs)方法快速实现列表视图,返回200状态码. 该Mixin的list方法 ...

  9. DRF (Django REST framework) 中的Request 与 Response

    DRF中的Request 与 Response 1. Request - REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST f ...

随机推荐

  1. Docker(十二):Docker集群管理之Compose

    1.Compose安装 curl -L https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname ...

  2. 阅读MDN文档之层叠与继承(二)

    目录 The cascade Importance Specificity Source order A note on rule mixing Inheritance Controlling inh ...

  3. lambda表达式不使用委托(delegate) 用FUNC

    lLambda不使用delegate关键字,而使用  Lambda运算符 => goes to l    1.Func<int,string> getInput = (int age ...

  4. Sticky Footer 绝对底部的两种套路

    最近面了好几个前端,工作经验有高有低,居然都不知道绝对底部是什么,也没有人能说出一种实现方式,让我不禁感慨前端领域的良莠不齐 绝对底部,或者说 Sticky Footer,是一种古老且经典的页面效果: ...

  5. Git上传项目到GitHub

    1.注册账户 https://github.com/ 2.创建仓库 3.需要安装 Git   http://msysgit.github.com/ 4.本地创建ssh key(不是必要,不创建ssh可 ...

  6. CSS3 美女动画相框

    把下面的内容放到一个body内,运行看一看:) <style> *{ margin:0; padding:0;} .bg1{ background-image:-moz-linear-gr ...

  7. Windows上最大传输单元MTU值的查看和设置

    最近使用ssh工具在VPN环境下连接一个生产环境的Linux主机的时候,发现经常出现输入命令后卡死的情况.最开始以为是Linux主机的问题,问了一些老同事之后发现原来是我自己电脑的最大传输单元MTU和 ...

  8. js 对象的值传递

    一.变量赋值的不同 1.原始值 在将一个保存着原始值的变量复制给另一个变量时,会将原始值的副本赋值给新变量,此后这两个变量是完全独立的. 2.引用值: 在将一个保存着对象内存地址的变量复制给另一个变量 ...

  9. 【转1】Appium 1.6.3 在Xcode 8, iOS 10.2(模拟器)测试环境搭建 经验总结

    Appium 1.6.3 在Xcode 8, iOS 10.2(模拟器)测试环境搭建 经验总结 关于 Appium 1.6.3 在Xcode 8, 10.2 的iOS模拟器上的问题很多,本人也差点放弃 ...

  10. 【Tarjan缩点】PO3352 Road Construction

    Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12532   Accepted: 630 ...