视图家族

一、views视图类

1、APIView类

功能:

  1. 拥有view的所有属性和方法;
  2. 重写as_view,禁用csrf;
  3. 重写dispatch,分发任务,五大模块对数据进行二次封装;
  4. 设定了一系列类属性。

2、GenericAPIView类(generics中)

特点:

  1. 继承APIView,所以拥有APIView的所有属性和方法;
  2. get_queryset方法,配置queryset类属性,提供视图类相关的Models;
  3. 在第二条的基础上,get_object方法,配置look_url_kwarg类属性,提供视图类的具体Model;
  4. get_serializer方法,配置serializer_class类属性,提供视图类相关的序列化对象。

分析:

class GenericAPIView(views.APIView):

    def get_queryset(self):
获取自定义类中设定的queryset对象。 def get_serializer(self):
调用get_serializer_class方法;
获取自定义类中设定的serializer_class序列化类 def get_object(self):
首先通过get_queryset获取自定义类中给定的queryset对象;
然后获取自定义类中设定的lookup_url_kwarg过滤参数;
如果没有就使用默认的 lookup_field='pk' 过滤参数;
使用过滤参数对queryset对象进行过滤; 因此,在继承GenericAPIView来自定义类时,需要定义queryset、serializer_class及lookup_url_kwarg(非必要)

目的:

视图中的增删改查逻辑相似,但操作的资源不一致,操作资源包括:[操作单个资源对象]、[操作多个资源对象]以及[资源相关的序列化类],将这三者形成配置,那操作逻辑就一致,就可以进行封装。

总结:

GenericAPIView就是在APIView基础上额外提供了三个方法,三个类属性,如果不配合视图工具类,体现不出优势。

二、mixins类:视图辅助工具

特点:

  1. 需要配合GenericAPIView类使用;
  2. 将单查、群查、单增、群增、单整体改,单局部改所对应的六个接口写成retrieve、list、create、update、partial_update、destroy六个方法,封装到五个类中;
  3. 以上六个方法中需要用到GenericAPIView提供的三大方法,因此需要GenericAPIView类的配合;
  4. 默认返回的只有序列化后的对象包含的内容。

1、RetrieveModelMixin

单查

class RetrieveModelMixin:
def retrieve(self, request, *args, **kwargs):
实现单查。 如果可以检索对象,则返回 200 OK 响应;
将该对象的序列化表示作为响应的主体。 否则将返回 404 Not Found。

2、ListModelMixin

群查

class ListModelMixin:
def list(self, request, *args, **kwargs):
实现群查; 如果查询集被填充了数据,则返回 200 OK 响应;
将查询集的序列化表示作为响应的主体。
相应数据可以任意分页。

3、CreateModelMixin

单增

class CreateModelMixin:
def create(self, request, *args, **kwargs):
实现单增。 如果创建了一个对象,将返回一个 201 Created 响应;
将该对象的序列化表示作为响应的主体。 如果为创建对象提供的请求数据无效,将返回 400 Bad Request;
其中错误详细信息作为响应的正文。

4、UpdateModelMixin

单整体改和单局部改

class UpdateModelMixin:
def update(self, request, *args, **kwargs):
完成单整体改; def partial_update(self, request, *args, **kwargs):
完成单局部改; 如果更新成功,将返回一个 200 OK 响应;
将对象的序列化表示作为响应的主体。 如果更新失败,将返回一个 400 Bad Request 响应;
错误详细信息作为响应的正文。

5、DestroyModelMixin

单删

class DestroyModelMixin:
def destroy(self, request, *args, **kwargs):
完成单删;
如果删除对象,则返回 204 No Content 响应;
否则返回 404 Not Found。

三、generics类:包含辅助工具的通用视图类

九个通用视图。

这通常是你真正用到的那些,除非你需要深度定制的行为。

这些视图类可以从 rest_framework.generics导入。

class RetrieveAPIView(mixins.RetrieveModelMixin,
GenericAPIView):
完成单查
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs) class ListAPIView(mixins.ListModelMixin,
GenericAPIView):
完成群查
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs) class CreateAPIView(mixins.CreateModelMixin,
GenericAPIView):
完成单增
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs) class UpdateAPIView(mixins.UpdateModelMixin,
GenericAPIView):
单整体改
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs) 单局部改
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs) class DestroyAPIView(mixins.DestroyModelMixin,
GenericAPIView):
完成单删
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs) class ListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView):
群查
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 RetrieveUpdateAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
GenericAPIView):
单查
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 patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs) class RetrieveDestroyAPIView(mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
单查
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
单删
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs) class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
单查
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 patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
单删
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)

四、viewsets视图集

包含:

一个工具类、两个视图集基类、两个视图集子类

1、作用

其中一个工具类重写了as_view方法,将自己定义的群查和单查方法的函数地址赋给get方法,这样就可以在路由来调用时,主动识别调用单查还是群查。

2、如何使用

路由中:as_view({'get':'list'}) 传入的{'get':'list'}就被actions接收,原理是将get请求映射给视图类的list函数进行处理。

class ViewSetMixin:
视图集都继承了ViewSetMixin类,该类重写了as_view方法,相比APIView的as_view方法,额外多出了一个参数:actions。 @classonlymethod
def as_view(cls, actions=None, **initkwargs): class ViewSet(ViewSetMixin, views.APIView): pass class GenericViewSet(ViewSetMixin, generics.GenericAPIView): pass class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet): pass class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet): pass
  1. GenericViewSet和ViewSet两个基类有什么区别:

    • GenericViewSet(ViewSetMixin,GenericAPIView):该分支严格满足资源接口
    • ViewSet(ViewSetMixin,APIView):该分支满足的接口与资源Model类关系不是特别密切(登录接口、短信验证码接口)
  2. ReadOnlyModelViewSet,ModelViewSet两个视图集子类,就是做个一堆mixin与GenericViewSet相结合,自己在urls文件中配置as_view的action分发。

3、ModelViewSet的不合理之处及解决方法

不合理之处:

  1. 没有群增,群整体改,群局部改,群删四个接口
  2. 删除操作视图集默认走的destroy方法是将资源从数据库中删除,通常一个做字段is_delete字段修改表示删除
  3. 响应的结果只有数据,没有数据状态码和状态信息

解决方法:

  1. 群整体改,群局部改,全删三个接口可以独立成三个方法

    def many_update(self, request, *args, **kwargs):
    pass
    def many_partial_update(self, request, *args, **kwargs):
    pass
    def many_destroy(self, request, *args, **kwargs):
    pass
    • 群增与单增必须公用一个接口,都要走create方法 - 重写create方法,用逻辑进行拆分
    def create(self, request, *args, **kwargs):
    request_data = request.data
    if isinstance(request_data, list):
    car_ser = self.get_serializer(data=request_data, many=True)
    car_ser.is_valid(raise_exception=True)
    car_obj = car_ser.save()
    return APIResponse(msg='群增成功', results=self.get_serializer(car_obj, many=True).data) return super().create(request, *args, **kwargs)
  2. destroy方法是完成is_delete字段值修改 - 重写destroy方法,自定义实现体

    def destroy(self, request, *args, **kwargs):
    car_obj = self.get_object()
    car_obj.is_delete = True
    car_obj.save()
    return APIResponse(msg='删除成功')
  3. 让群查有状态码和状态信息 - 重写list方法

    def list(self, request, *args, **kwargs):
    response = super().list(request, *args, **kwargs)
    return APIResponse(results=response.data)

路由层补充

路由的其他写法:SimpleRouter

会遇到,看到了要认识:

# urls.py
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('v2/cars', views.CarModelViewSet, basename='car') urlpatterns = [
url(r'^v1/cars/$', views.CarAPIView.as_view()), url(r'', include(router.urls))
]
/
urlpatterns += router.urls
/
urlpatterns = router.urls

DRF 视图家族及路由层补充的更多相关文章

  1. DRF视图集的路由设置

    在使用DRF视图集时,往往需要配一大堆路由,例如: # views.py class DepartmentViewSet(ListModelMixin,CreateModelMixin,Retriev ...

  2. day73:drf:drf视图相关类&路由Routers&创建虚拟环境

    目录 1.APIView 2.GenericAPIView:通用视图类 3.5个视图扩展类:ListModelMixin,CreateModelMixin,RetrieveModelMixin,Upd ...

  3. drf框架 - 视图家族 | GenericAPIView | mixins | generics | viewsets

    视图家族 view:视图 generics:工具视图 mixins:视图工具集 viewsets:视图集 学习曲线: APIView => GenericAPIView => mixins ...

  4. django之表设计、路由层等

    图书管理系统表的设计 from django.db import models # Create your models here. class Book(models.Model): title = ...

  5. drf二次封装response-APIViews视图家族-视图工具集-工具视图-路由组件

    视图类传递参数给序列化类 (1).在视图类中实例化 序列化对象时,可以设置context内容. (2).在序列化类中的局部钩子.全局钩子.create.update方法中,都可以用self.conte ...

  6. Django-1版本的路由层、Django的视图层和模板层

    一.Django-1版本的路由层(URLconf) URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:我们就是以这种方式告诉Dja ...

  7. Django系列(二):Django的路由层,视图层和模板层

    1.Django的路由层 URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:我们就是以这种方式告诉Django,对于客户端发来的某 ...

  8. 视图家族 & 路由组件

    目录 视图家族 & 路由组件 视图集与路由组件 基于 GenericAPIView 的十大接口 基于 generics 包下工具视图类的六大基础接口 视图集 路由组件:必须配合视图集使用 自定 ...

  9. Django之路由层和视图层详解

    路由层 首先我们来看一下,路由层都有哪些东西,其实你看django很人性化,将所有的介绍都放在了简介里面,不信,你看

随机推荐

  1. 前端基础之html学习一:

    网站的建站流程 页面图例 网页的结构 WEB标准 WEB标准是网页制作的标准,它不是一个标准,它是根据网页的不同组成部分生成的一系列标准.这些标准大部分由W3C起草发布,也有部分标准由ECMA起草发布 ...

  2. 2019牛客暑期多校训练营(第六场)D-Move

    >传送门< 题意: 你有n件行李,有k个箱子体积相同的箱子,遵循下面的规则将行李放进箱子里面 每次都取当前最大的可以放进箱子的行李放进箱子,如果该箱子放不进任何行李那么就换一个新的箱子再按 ...

  3. Codeforces Round #628 (Div. 2) C. Ehab and Path-etic MEXs(树,思维题)

    题意: 给有 n 个点的树的 n-1 条边从 0 到 n-2 编号,使得任意两点路径中未出现的最小数最小的方案. 思路: 先给所有度为 1 的点所在边编号,之后其他点可以随意编排. #include ...

  4. Codeforces Round #649 (Div. 2) B. Most socially-distanced subsequence

    题目链接:https://codeforces.com/contest/1364/problem/B 题意 给出大小为 $n$ 的一个排列 $p$,找出子序列 $s$,使得 $|s_1-s_2|+|s ...

  5. 【noi 2.6_7113】Charm Bracelet(DP)

    题意:N个饰物,有重量和渴望程度.问在M的重量限制内能达到的最大的渴望度. 解法:经典的01问题,但有一个小技巧值得记住:用if比较大小比调用max函数快了不少,这题有100ms左右. 1 #incl ...

  6. 牛客53680 「金」点石成金 (dfs)

    题意:给你\(n\)组数,每组4个正整数\(a,b,c,d\),每组数有两个选择: ​ 1.增加\(a\)个财富,消耗\(b\)点魔法. ​ 2.回复\(c\)点魔法,减少\(a\)个财富. 求最后财 ...

  7. AtCoder Beginner Contest 179 E - Sequence Sum (模拟)

    题意:\(f(x,m)\)表示\(x\ mod\ m\),\(A_{1}=1\),而\(A_{n+1}=f(A^{2}_{n},M)\),求\(\sum^{n}_{i=1}A_{i}\). 题解:多算 ...

  8. CF1474-B. Different Divisors

    CF1474-B. Different Divisors 题意: 题目给出你一个\(d\),要求你找出一个数字\(y\),找到的\(y\)至少有四个整数因子并且任意两个因子之间的差至少为\(d\). ...

  9. markdown 公式编写及不同平台公式转换

    1.markdown 用法及公式编写,这块就不再重复,已有很多官方平台的文档说明很完善 有道云markdown写作文档 在博客园中插入公式 markdown公式输入(特殊符号) markdown 特殊 ...

  10. Navicat 使用 SSH 通道

    使用 Navicat for MySQL 通过跳板机登录 Mysql 时(使用 SSH 通道) 报错如下: SSH : Expected key exchange group packet from ...