Django REST Framework(DRF)_第二篇
视图和路由
视图封装
第一次封装
上一篇最后我们对书籍表做了增删改查,那么如果现在我们有几十上百张表需要这样做呢?我们知道类的特性有封装,因此我们可以尝试进行封装下.
from rest_framework.views import APIView
from rest_framework.response import Response from .models import Book
from .modelSerializers import BookModelSerializer class GenericAPIView(APIView):
queryset = None
serializer_class = None def get_queryset(self):
return self.queryset.all() def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs) class ListModelMixin(object):
# 这个就是把get方法抽离了出来,变成了list方法
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
serializer_data = self.get_serializer(queryset, many=True)
return Response(serializer_data.data) class CreateModelMixin(object):
def create(self, request, *args, **kwargs):
ser_obj = self.get_serializer(data=request.data)
if ser_obj.is_valid():
ser_obj.save()
return Response(ser_obj.validated_data)
return Response(ser_obj.errors) class RetrieveModelMixin(object):
def retrieve(self, request, id, *args, **kwargs):
book_obj = self.get_queryset().filter(pk=id).first()
ser_obj = self.get_serializer(book_obj)
return Response(ser_obj.data) class UpdateModelMixin(object):
def update(self, request, id, *args, **kwargs):
book_obj = self.get_queryset().filter(pk=id).first()
ser_obj = self.get_serializer(instance=book_obj, data=request.data, partial=True)
if ser_obj.is_valid():
ser_obj.save()
return Response(ser_obj.validated_data)
return Response(ser_obj.errors) class DestroyModeMixin(object):
def destroy(self, request, id , *args, **kwargs):
book_obj = self.get_queryset().filter(id=id).first()
if not book_obj:
return Response("要删除的对象不存在")
book_obj.delete()
return Response("") class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):
pass class RetrieveUpdateDestroyAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModeMixin):
pass class BookView(ListCreateAPIView):
"""书籍相关视图"""
queryset = Book.objects
serializer_class = BookModelSerializer def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs) class BookEditView(RetrieveUpdateDestroyAPIView):
queryset = Book.objects
serializer_class = BookModelSerializer def get(self, request, id, *args, **kwargs):
return self.retrieve(request, id, *args, **kwargs) def put(self, request, id, *args, **kwargs):
return self.update(request, id, *args, **kwargs) def delete(self, request, id, *args, **kwargs):
return self.destroy(request, id, *args, **kwargs)
从上面我们可以知道,我们发现视图中就只有query和ModelSerializer每个方法不一样,因此,我们先定义了一个GenericAPIView,该方法就是专门获取query和ModelSerializer.再接着就是将get全部/get单条/post/put/delete方法分别再次封装到不同类中的方法中,这样在写多个表时只需要调用方法即可,但是此时你会发现继承的类有点长,因此又封装了两个类专门继承多个类,这样我们再写就只需要继承一个类了,你看这样是不是变得更简单了,我们必须学习这种封装的思想,使得自己代码更加简洁,复用性更高.
二次最终封装
上面封装似乎已经很好了,但是人总是贪婪的,上面是不是定义了两个视图针对不同操作(BookView和BookEditView),那我们想能不能只定义一个视图就完成呢?此时我们去看一下rest_framework提供的源码
在这里先被备注下rest_framework给我们的几个视图相关的类
from rest_framework import views # 里面主要是有APIView
from rest_framework import viewsets # ModelViewSet封装,继承mixins下的各个类
from rest_framework import generics # GenericAPIView,CreateAPIView等封装
from rest_framework import mixins # list,create,update等方法具体实现因为我们需要合并视图,所以我们需要在as_view()时出入对应关系的参数,所以我们看下viewsets下的ViewSetMixin类, from rest_framework.viewsets import ViewSetMixin.
从ViewSetMixin中我们可以知道,重写了as_view()方法,并且将参数传给了action,这里我只拿出了一些需要的代码进行说明下.
def as_view(cls, actions=None, **initkwargs):
# actions = {"get": "list", "post": "create"}
def view(request, *args, **kwargs):
for method, action in actions.items():
# method = get, action = list
handler = getattr(self, action)
# 这里就将self.get = self.list,所以之后get请求就会去找list方法
setattr(self, method, handler)所以注意下,只有继承了ViewSetMixin路由才可以传参,前面说完了,我们来再次封装下代码:
views下就变成了
class ModelViewSet(ViewSetMixin, ListCreateAPIView, RetrieveUpdateDestroyAPIView):
pass class BooksView(ModelViewSet):
queryset = Book.objects
serializer_class = BookModelSerializerurls下变成
path('books', views.BooksView.as_view({"get": "list", "post": "create"})),
re_path('book/(?P<id>\d+)', views.BooksView.as_view({"get": "retrieve", "patch": "update", "delete": "destroy"})),其实我们辗转了大半天,人家早就给我们封装好了,views下我们啥都不用写,就只需要继承人家封装好的就可以了,就下面几行代码即可
DRF视图最终写法
from rest_framework import viewsets
class BooksView(viewsets.ModelViewSet):
queryset = Book.objects
serializer_class = BookModelSerializer但是urls那里不能写id了,只能写pk
path('books', views.BooksView.as_view({"get": "list", "post": "create"})),
re_path('book/(?P<pk>\d+)', views.BooksView.as_view({"get": "retrieve", "patch": "update", "delete": "destroy"})),
DRF路由
思考下,如果我们要写几十张表的路由,那岂不是又要每个路由传一堆一样的参数?别怕,DRF又帮我们搞定了,我们只需要按照下面的方式写即可
from rest_framework.routers import DefaultRouter # 实例化DefaultRouter
router = DefaultRouter()
# 注册路由以及视图
router.register(r"book", views.BooksView) # 将路由url加入到urlpatterns
urlpatterns += router.urls该方法虽然简洁快速,但也会暴露很多路由接口,视情况选择使用.
Django REST Framework(DRF)_第二篇的更多相关文章
- Django REST Framework(DRF)_第一篇
认识RESTful REST是设计风格而不是标准,简单来讲REST规定url是用来唯一定位资源,而http请求方式则用来区分用户行为. REST接口设计规范 HTTP常用动词 GET /books:列 ...
- Django REST Framework(DRF)_第四篇
DRF分页(总共三种) PageNumberPagination(指定第n页,每页显示n条数据) 说明 既然要用人家的那么我们就先来看下源码,这个分页类源码中举例通过参数指定第几页和每页显示的数据:h ...
- Django REST Framework(DRF)_第三篇
DRF版本控制 介绍 我们在看APIView源码时可以看到,版本和版本控制类是通过determine_version的返回值获取的 version, scheme = self.determine_v ...
- Django 学习之Django Rest Framework(DRF)
一. WEB应用模式 在开发Web应用中,有两种应用模式 1. 前后端不分离 把html模板文件和django的模板语法结合渲染完成以后才从服务器返回给客户. 2. 前后端分离 二. API接口 AP ...
- day71:drf:API接口&Restful API规范&Django Rest Framework&drf中的序列化和反序列化功能
目录 1.web应用模式 2.API接口 3.Restful API规范 4.序列化 5.Django Rest Framework 1.drf的简单介绍 2.drf的特点 3.如何安装drf 4.d ...
- Matlab高级教程_第二篇:关于MATLAB转C#过程中遇到输出两组参数的问题
1. 在matlab的m函数很可能遇到原函数[a,b] = func(a); 这样的两个输出参数. 2. 在观察C#生成后定义中我们发现: public MWArray HP(); public MW ...
- Python全栈开发记录_第二篇(文件操作及三级菜单栏增删改查)
python3文件读写操作(本篇代码大约100行) f = open(xxx.txt, "r", encoding="utf-8") 不写“r”(只读)默认是只 ...
- Python笔记_第二篇_面向过程_第二部分_2.路径、栈和队列、内存修改
这一部分分三个主题进行讲解,主要为后面的模块.包.第三方库的概念补充一些相关的内容. 1. 路径(Path): 相对路径和绝对路径. 举例1:我们先导入一个os库(模块)来观察一下路径 import ...
- Matlab高级教程_第二篇:Matlab相见恨晚的模块_02_并行运算-1
1 更高级的算法牵扯到更多重的循环和复杂的计算,尤其是现在人工智能的算法尤其如此.有些历史知识的人能够了解到,人工智能的很多基本算法其实近百年之前就有了,但是当时的计算机技术达不到去实现这些算法的要求 ...
随机推荐
- VS2010下编译配置Boost_1.53
一.准备工作 1.下载最新版本的boost库.所在地址:boost_1_53_0.zip.官方推荐7z压缩格式的,因为其压缩效率更好,相应包的大小也比较小. 2.解压缩到指定目录,如C:\boost_ ...
- 从零开始人工智能AI(一)-k-nn-矩阵
参考资料: https://baike.baidu.com/item/%E7%9F%A9%E9%98%B5/18069?fr=aladdin http://blog.csdn.net/c4064957 ...
- Java集合框架Collection(1)ArrayList的三种遍历方法
ArrayList是java最重要的数据结构之一,日常工作中经常用到的就是ArrayList的遍历,经过总结,发现大致有三种,上代码: package com.company; import java ...
- python的实用函数
>>> file=open('txt.txt','a') >>> print >> file,'hello,world' >>> fi ...
- java基础(1)-几种获取类的扩展方式
摘要 在日常开发过程中经常需要获取类的扩展集.即获取类的子类集(抽象类),或者接口实现类.比如说状态模式中,状态构建类,策略模式中的,策略构造方式.本文介绍几种获取方式. 实现 以策略模式为例 定义了 ...
- 视频直播:Windows中各类画面源的截取和合成方法总结
当今,视频直播技术和实时音视频技术已经是很多行业必备,典型的应用场景有教育直播.远程视频会议.互联网娱乐等.在移动端发起直播,其画面源的种类是十分有限的,无非是取摄像头.截屏等.PC端由于其系统资源充 ...
- OVS实现VXLAN隔离
一.实验环境 1.准备3个CentOS7 mini版本的虚拟机,每个主机3个网卡.如图: 图中OVS-1.OVS-2.OVS-3分别为三台CentOS7 mini版虚拟机,分别配备3个虚拟网卡.如图中 ...
- 【转载】tomcat原理
转载地址:https://blog.csdn.net/u014795347/article/details/52328221?locationNum=2&fps=1 以下代码纯属本人复制,而且 ...
- ASP.NET Core on K8S学习初探(2)K8S基本概念快速一览
在上一篇<单节点环境搭建>中,通过Docker for Windows在Windows开发机中搭建了一个单节点的K8S环境,接下来就是动人心弦的部署ASP.NET Core API到K8S ...
- docker相关使用
安装docker 在CentOS 7上安装docker-ce,首先检查系统中是否已经安装过docker及相关依赖: $ sudo yum remove docker docker-client doc ...