Django编写RESTful API(三):基于类的视图
欢迎访问我的个人网站:www.comingnext.cn
前言
在上一篇文章中,主要讲的是请求和响应,项目里面views.py中的视图函数都是基于函数的,并且我们介绍了@api_view这个很有用的装饰器。同时,我们还介绍了APIView这个类,但是还没使用它。在这篇文章中,我们要做的是把基于方法的视图改为基于类的视图,将会了解到APIView。
改为基于类的视图
重构一下snippets/view.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)
到这里应该很容易理解,和原来的相比,可以发现基于类的视图把各种不同的HTTP请求分离开变成单个的方法,而不是if...elif...这样的结构,所以这样处理起来很更加的高效。
同样的,把另一个视图函数也进行修改:
- 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)
改为基于类的视图之后,当然也要修改一下路由了,对snippets/urls.py稍加修改:
- from django.conf.urls import url
- from rest_framework.urlpatterns import format_suffix_patterns
- from snippets import views
- urlpatterns = [
- url(r'^snippets/$', views.SnippetList.as_view()),
- url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
- ]
- urlpatterns = format_suffix_patterns(urlpatterns)
这样就可以运行程序了,功能和之前的是一样的
使用mixins类
使用基于类的视图的好处除了上面所说的把各种HTTP请求分离开,还有什么好处吗?答案是肯定的——使用基于类的视图的最大优势之一是它可以轻松地构成可重复使用的行为。
可重复使用的行为?简单说,就是让我们少写一点功能类似的代码,由此就要介绍一下mixins类了,它帮我们封装了很多操作,简化代码,使用也很简单,编辑snippets/view.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)
新的视图类中继承了 generic.GenericAPIView、mixins.ListModelMixin和mixins.CreatteModelMixin,类的作用看字面意思就能懂啦,mixins类为我们提供了list()和create()方法,当然,使用这两个函数需要先设置queryset和serializer_class,这点我们查看一下mixins的源码就可以看出来了,比如list方法:
- class ListModelMixin(object):
- """
- List a queryset.
- """
- def list(self, request, *args, **kwargs):
- queryset = self.filter_queryset(self.get_queryset())
- page = self.paginate_queryset(queryset)
- if page is not None:
- serializer = self.get_serializer(page, many=True)
- return self.get_paginated_response(serializer.data)
- serializer = self.get_serializer(queryset, many=True)
- return Response(serializer.data)
这里的代码会分别通过get_queryset()和get_serializer()得到查询集和序列化器,其他封装好的方法也是如此。
知道了这个,再修改一下另一个视图类就很容易了:
- 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)
使用通用的视图类
到这里,视图代码已经简化了许多了,但是我要告诉你的是,还可以进一步简化。。。在此,让我们一起在心中默念:
人生苦短,我用Python
进一步简化就是连mixins类都不用了,只使用generics就可以了,代码如下:
- 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
好了,现在的代码就显得非常简洁了,但是短小却精悍,依然可以实现原本的功能,随意的展示一下:
把基于函数的视图改成基于类的视图就讲到这里了,下一篇文章会介绍授权和权限~
本文地址:http://www.cnblogs.com/zivwong/p/7434523.html
作者博客:ziv
欢迎转载,请在明显位置给出出处及链接
Django编写RESTful API(三):基于类的视图的更多相关文章
- Django编写RESTful API(一):序列化
欢迎访问我的个人网站:www.comingnext.cn 关于RESTful API 现在,在开发的过程中,我们经常会听到前后端分离这个技术名词,顾名思义,就是前台的开发和后台的开发分离开.这个技术方 ...
- Django编写RESTful API(四):认证和权限
欢迎访问我的个人网站:www.comingnext.cn 前言: 按照前面几篇文章里那样做,使用Django编写RESTful API的基本功能已经像模像样了.我们可以通过不同的URL访问到不同的资源 ...
- Django编写RESTful API(六):ViewSets和Routers
欢迎访问我的个人网站:www.comingnext.cn 前言 在本系列的文章中,我在第一篇和第二篇文章中写的编写Django视图时,使用的都是基于函数的方法,并且每个视图函数之前都会加一个djang ...
- Django编写RESTful API(二):请求和响应
欢迎访问我的个人网站:www.comingnext.cn 前言 在上一篇文章,已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful API的一个理念,每一个URL代表着一个资源.当然我 ...
- Spring Boot 2.x 编写 RESTful API (三) 程序层次 & 数据传输
用Spring Boot编写RESTful API 学习笔记 程序的层次结构 相邻层级的数据传输 JavaBean 有一个 public 的无参构造方法 属性 private,且可以通过 get.se ...
- Django编写RESTful API(五):添加超链接提高模型间的关联性
前言 在第四篇中,加入了用户模型,以及相关的认证和权限的功能.但是我们在使用的时候,会发现在访问http://127.0.0.1:8000/users/时看到的用户列表,不能够直接点击某个链接然后查看 ...
- django 中基于类的视图
django 视图 分为两种: 1. FBV 基于函数的视图 function based view 2. CBV 基于类的视图 class based ...
- python 全栈开发,Day95(RESTful API介绍,基于Django实现RESTful API,DRF 序列化)
昨日内容回顾 1. rest framework serializer(序列化)的简单使用 QuerySet([ obj, obj, obj]) --> JSON格式数据 0. 安装和导入: p ...
- 利用 Django REST framework 编写 RESTful API
利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framewor ...
随机推荐
- 初学Python(一)——数据类型
初学Python(一)——数据类型 初学Python,主要整理一些学习到的知识点,这次是数据类型. #-*- coding:utf-8 -*- #整数 print 1 #浮点数=小数 print 1. ...
- 关于bootstrap的一些想法
老实说,作为一个前端人员,我不怎么会去用bootstrap,但是我会去看,会去了解. 首先,bootstrap其实是给后台以及前端新人用来快速完成一个页面的简单布局,不是按照设计稿psd格式给定做的那 ...
- WPF--TextBlock的ToolTip附加属性
大家可能在项目中,有的时候,由于显示的内容过长,所以,需要显示一部分内容,然后后面用省略号,把鼠标放上去,会显示出来全部的内容. 作为一个LowB程序员的我,第一反应是SubString截取,然后替换 ...
- 详解Tomcat 配置文件server.xml
前言 Tomcat隶属于Apache基金会,是开源的轻量级Web应用服务器,使用非常广泛.server.xml是Tomcat中最重要的配置文件,server.xml的每一个元素都对应了Tomcat中的 ...
- CLI子命令扩展-插件机制实现
开发CLI工具过程中,为了便于扩展,将CLI的实现分为基础功能和扩展功能.基础功能包括init.build.lint.publish等伴随工程从初始化到最终发布到生产环境,也即为CLI 的core.扩 ...
- Zabbix监控IO
导入模板 configuration->templates->import,选择你需要导入的模板文件 #zabbix_agentd配置 # iostat #磁盘读的次数 UserParam ...
- vue指令v-on示例解析
绑定事件监听器.事件类型由参数指定.表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略. 1.事件 .click .mouseover .keyup ...... 2.修饰符 .sto ...
- HPU--1280 Divisible
题目描述 给定一个很大的整数,我想知道它能否被9整除. 输入 有t组测试数据,每组数据给定一个整数N不存在前导0.(1 <= t <= 20,1 <= N <= 10^200) ...
- CSS禁止用户选择复制
-webkit-user-select:none ;-moz-user-select:none; P.S. -wekit-gg浏览器 -moz -ff浏览器 WebKit 是一个开源的浏览器引擎,与之 ...
- SELECT中的if_case流程函数
DQL中常用的流程函数if_case ---流程函数在一个SQL语句中实现条件选择 模拟对职员薪水进行分类: mysql> create table salary_tab(userid ,)); ...