从介绍Django快开始,我们就一直在使用FBV的方式来撰写代码,二者本质上并没有太大的区别,然而到了REST framework,更会倾向于用CBV来写API的视图,后面会看到这个方式的强大,它允许我们重用常用的功能,让代码更简练。

Rewriting Our API using class-based view

现在开始撰写一个简单的CBV代码,打开app内的views.py文件

from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from django.http import Http404
from app01.models import Snippet
from app01.serializers import SnippetSerializer class SnippetList(APIView):
"""
列出所有的对象或者创建一个新的对象
"""
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方法间更好的分离,来更新一下上述实例的代码,还是在app的views.py文件。

class SnippetDetail(APIView):
"""
获取、更新、删除一个实例对象
"""
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)

这段代码看起来很棒,但是它现在还是跟FBV的代码很像。

同时,还需要稍微重构app内的urls文件,现在需要用CBV的方式。

from app01 import views
from django.urls import path, include
from rest_framework.urlpatterns import format_suffix_patterns urlpatterns = [
path('snippets/', views.SnippetList.as_view()),
path('snippets/<int:pk>/', views.SnippetDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)

好了,我们已经完成了。如果你将代码允许起来,应该跟之前的效果一样。

Using mixins

使用CBV的的最大优点之一就是,它允许我们很容易的编写一些可重用的行为。

到目前为止,创建、删除、更新、获取这些操作在任何模型支持的API视图中都是非常相似的。

一起来看下,如何使用mixin类来构建视图。再次修改view.py文件

from app01.models import Snippet
from app01.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,同时也继承了ListModelMixin和CreateModelMixin

基类提供了核心的功能,mixin类提供了.list()和.create()操作。然后,明确的绑定了get和post方法到合适的行为。到目前为止,足够简单。

继续改造另一个CBV

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)

跟上面的CBV非常相似。同样的,我们再一次使用GenericAPIView来提供核心代码,然后使用mixin中的.retrieve(), .update(), .destory()方法。

Using generic class-based views

上面使用mixin类使用比之前更少的代码稍微重写了视图,但是我们还能更上一层楼。REST framework提供了一系列已经混合封装好的generic视图,进而可以直接在views.py文件内简化使用。

from app01.models import Snippet
from app01.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

看到这里,不免会惊叹,OMG!这也太简洁了。我们免费得到了大量的代码,我们的代码看起来很好,很干净,很符合语言习惯的Django。

Django REST framework 第三章 CBV的更多相关文章

  1. Django REST framework 第六章 ViewSets & Routers

    REST framework包含了一个可以处理ViewSets的抽象, 它允许开发人员专注于API的状态跟交互进行建模,并使得URL构建结构基于通用的约定自动处理. ViewSet类跟View类几乎相 ...

  2. Django REST framework 第四章 Authentication

    到目前为止,撰写的API没有任何限制关于谁能更新.删除snippet. 我们更想要一些高级行为来确保: 1.代码段总是跟创建者有关联 2.只要认证通过的用户才能创建 3.只有创建者有权限更新或者删除 ...

  3. Django REST framework 第五章 Relationships & Hyperlinked APIs

    到目前为止,API内部的关系是使用主键来代表的.在这篇教程中,我们将提高API的凝聚力和可发现性,通过在相互关系上使用超链接. Creating an endpoint for the root of ...

  4. (转)Django学习之 第三章:动态Web页面基础

    上一章我们解释了怎样开始一个Django项目和运行Django服务器 当然了,这个站点实际上什么也没有做------除了显示了"It worked"这条信息以外. 这一章我们介绍怎 ...

  5. Django REST framework 第七章 Schemas & client libraries

    模式是一个机器可读文档,描述可用的API端点,URL以及它们支持的操作. 模式对于自动生成文档是一个很有用的工具,也可以用来动态调用可以于API交互的客户端库. Core API 为了提供模式支持,R ...

  6. Django Rest framework实现流程

    目录 一 什么是restful架构 二 Django REST framework简介 三 Django REST framework原理 四 Django REST framework源码流程 五 ...

  7. Django REST framework+Vue 打造生鲜电商项目(笔记二)

    (转自https://www.cnblogs.com/derek1184405959/p/8768059.html)(有修改) 接下来开始引入django resfulframework,体现它的强大 ...

  8. 《Django By Example》第三章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:第三章滚烫出炉,大家请不要吐槽文中 ...

  9. python 全栈开发,Day94(Promise,箭头函数,Django REST framework,生成json数据三种方式,serializers,Postman使用,外部python脚本调用django)

    昨日内容回顾 1. 内容回顾 1. VueX VueX分三部分 1. state 2. mutations 3. actions 存放数据 修改数据的唯一方式 异步操作 修改state中数据的步骤: ...

随机推荐

  1. django基于中间件的IP访问频率控制

    一.中间件的代码 注意:成功时返回的是None,那样才会走视图层,返回httpresponse就直接出去了 import time from django.utils.deprecation impo ...

  2. bzoj2938 AC自动机 + 拓扑排序找环

    https://www.lydsy.com/JudgeOnline/problem.php?id=2938 题意:给出N个01病毒序列,询问是否存在一个无限长的串不存在病毒序列 正常来说,想要寻找一个 ...

  3. 解决openoffice进程异常退出的办法

    步骤1 编写脚本 openoffice.sh #!/usr/bin/bash OPENOFFICEPID=`ps -ef|grep "/opt/openoffice4/program/sof ...

  4. 剑指Offer_编程题_17

    题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构)   /* struct TreeNode { int val; struct TreeNode * ...

  5. collections 数据结构模块namedtuple

    namedtuple类 导入模块 from collections import namedtuple 使用方法及说明 #pycharm 里按住 ctrl键点击 collections可查看源码 #c ...

  6. netty的拆包和粘包

    第一种:自定义规则 比如说我们自己设定$_结尾的数据为一个整体. 看主要代码,大体不变,就多了几行代码.具体先看我上一篇的代码.这里只做修改 server端 b.childHandler(new Ch ...

  7. 开源图片文字识别引擎——Tesseract OCR

    Tessseract为一款开源.免费的OCR引擎,能够支持中文十分难得.虽然其识别效果不是很理想,但是对于要求不高的中小型项目来说,已经足够用了. 文字识别可应用于许多领域,如阅读.翻译.文献资料的检 ...

  8. GridView固定行宽,自动换行,鼠标放在Table的Tr上变色

    //固定行宽table-layout:fixed;//自动换行word-break :break-all;word-wrap:break-wordGridView.Attributes.Add(&qu ...

  9. MySQL 8.0X的安装与卸载命令

    1,下载 https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.12-winx64.zip 2,解压 将mysql-8.0.12-winx64 ...

  10. python--numpy、pandas

    numpy 与 pandas 都是用来对数据进行处理的模块, 前者以array 为主体,后者以 DataFrame 为主体(让我想起了Spark的DataFrame 或RDD) 有说 pandas 是 ...