Django REST framework 中 3 种类视图的对比
相较于使用基于方法(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 种类视图的对比的更多相关文章
- Django REST framework 中文文档
Django REST framework介绍 现在前后端分离的架构设计越来越流行,业界甚至出现了API优先的趋势. 显然API开发已经成为后端程序员的必备技能了,那作为Python程序员特别是把Dj ...
- DRF (Django REST framework) 中的视图类
视图说明 1. 两个基类 1)APIView rest_framework.views.APIView APIView是REST framework提供的所有视图的基类,继承自Django的View父 ...
- Django REST framework中的版本控制
1.REST framework版本控制的流程分析 1.1 determine_version方法的执行流程 首先,请求到达REST framework的CBV,执行CBV中的dispatch方法再次 ...
- Django rest framework(8)---- 视图和渲染器
django rest framework 之视图 序列化器 PagerSerialiser from rest_framework import serializers from api im ...
- 在django restful framework中设置django model的property
众所周知,在django的model中,可以某些字段设置@property和setter deleter getter,这样就可以在存入数据的时候进行一些操作,具体原理请参见廖雪峰大神的博客https ...
- JWT验证机制【刘新宇】【Django REST framework中使用JWT】
JWT 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证.我们不再使用Session认证机制,而使用Json Web Token认证机制. 什么是JWT Json web t ...
- Django REST framework 中的视图
1.Request REST framework传入视图的request对象不再是Django默认的Httprequest对象,而是DRF提供的扩展类的Request类的对象 常用属性 request ...
- DRF (Django REST framework) 中的视图扩展类
2. 五个扩展类 1)ListModelMixin 列表视图扩展类,提供list(request, *args, **kwargs)方法快速实现列表视图,返回200状态码. 该Mixin的list方法 ...
- DRF (Django REST framework) 中的Request 与 Response
DRF中的Request 与 Response 1. Request - REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST f ...
随机推荐
- treeview插件使用:根据子节点选中父节点
鄙人公司没有专门的前端,所以项目开发中都是前后端一起抡.最近用bootstrap用的比较频繁,发现bootstrap除了框架本身的样式组件外,还提供了多种插件供开发者选择.本篇博文讲的就是bootst ...
- DeepLearning.ai学习笔记(四)卷积神经网络 -- week1 卷积神经网络基础知识介绍
一.计算机视觉 如图示,之前课程中介绍的都是64* 64 3的图像,而一旦图像质量增加,例如变成1000 1000 * 3的时候那么此时的神经网络的计算量会巨大,显然这不现实.所以需要引入其他的方法来 ...
- arcgis api for js热力图优化篇-不依赖地图服务
前面我写过一篇文章,介绍如何实现arcgis api的热力图效果,但是依赖arcgis server发布的地图服务来获取热力图的数据源.实际应用中,很多业务数据来源数据库,并不一定是从地图服务来获取的 ...
- [置顶]
xamarin android 布局尺寸了解
为了使UI界面在不同大小的移动端显示器上能够正常显示,大家可能都知道使用sp作为字体大小的单位,dp作为其他元素长度的单位. 前几天看了一篇文章关于 App设计规范的,文章用心写的非常好,这里是链接 ...
- php-基于面向对象的MySQL类
class sqlHelper{ private $conn; private $host = 'localhost'; private $user = 'root'; private $pwd = ...
- Mysql5.7.20 On Windows安装指导
安装环境 Windows版本:Windows10 64bit MySQL版本: MySQL5.7.20 配置过程 1.下载MySQL Community Server (下载链接) 根据自己操作系统需 ...
- php运行C++程序
linux命令:gcc hello.cpp -lstdc++ -o hello.o php代码: <?php $command="./hello.o "; passthru( ...
- Linux文件的复制、删除和移动命令
cp命令 功能:将给出的文件或目录拷贝到另一文件或目录中,就如同DOS下的copy命令一样,功能非常强大. 语法:cp [选项] 源文件或目录 目标文件或目录 说明:该命令把指定的源文件复制到目 ...
- vue 全局插槽 全局插座
场景: slot 能够让父组件内容插入到子组件中,但是子孙组件不能够使用slot直接插入内容.在弹窗的时候,全屏弹窗需要直接在组件最上层显示,如果父组件级别不够,弹出就可能不是全屏的. 知识点: 1: ...
- 对vuex的认识和简单理解
vuex概述 Vuex 是一个主要应用在中大型单页应用的类似于 Flux 的数据管理架构.它主要帮我们更好地组织代码,以及把应用内的的状态保持在可维护.可理解的状态. 但如果是简单的应用 ,就没有必要 ...