77-drf视图家族及路由层补充

目录

  • 视图家族

    • 一、views视图类

      • 1、APIView类
      • 2、GenericAPIView类(generics中)
    • 二、mixins类:视图辅助工具
      • 1、RetrieveModelMixin
      • 2、ListModelMixin
      • 3、CreateModelMixin
      • 4、UpdateModelMixin
      • 5、DestroyModelMixin
    • 三、generics类:包含辅助工具的通用视图类
    • 四、viewsets视图集
      • 1、作用
      • 2、如何使用
      • 3、ModelViewSet的不合理之处及解决方法
  • 路由层补充

视图家族

一、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

原文地址:https://www.cnblogs.com/bowendown/p/12121962.html

时间: 2024-08-30 16:59:24

77-drf视图家族及路由层补充的相关文章

drf视图家族

视图类给序列化类传参 Response({ 'status': 0, 'msg': 'ok', 'results': [], 'token': '' # 有这样的额外的key-value数据结果 },status=http_status,headers=headers,exception=True|False) APIResponse() => Response({'status': 0,'msg': 'ok'}) from rest_framework.response import Resp

路由层 urls.py

1. 数据操作 ''' 表字段的增删改查: 新增的字段: 1.直接提供默认值 default 2.设置改字段可以为空 null=True 注意的是 不要轻易的注释models.py中任何跟数据库相关的代码 主要是跟数据库相关的代码 你在处理的时候一定要小心谨慎 ''' # 数据的增删改查: # 1.数据的查: # get(): res = models.User.objects.get(username=username) # 1.条件存在的情况下 获取的直接是数据对象本身 # 2.条件不存在的

django之表设计、路由层等

图书管理系统表的设计 from django.db import models # Create your models here. class Book(models.Model): title = models.CharField(max_length=32) # 总共八位 小数占两位 price = models.DecimalField( max_digits=8,decimal_places=2) # 书和出版社是一对多的关系 外键字段键在多的一方 publish = models.F

drf之视图类与路由

视图 Django REST framwork 提供的视图的主要作用: 控制序列化器的执行(检验.保存.转换数据) 控制数据库查询的执行 2个视图基类 APIView rest_framework.views.APIView APIView是REST framework提供的所有视图的基类,继承自Django的View父类. APIView与View的不同之处在于: 传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象: 视图方法

drf序列化高级、自定义只读只写、序列化覆盖字段、二次封装Response、数据库查询优化(断关联)、十大接口、视图家族、自动补全图片链接

目录 自定义只读 自定义只写 序列化覆盖字段 二次封装Response 数据库关系分析 断外键关联关系 ORM操作外键关系 ORM四种关联关系 基表 序列化类其他配置(了解) 十大接口 BaseSerializer初始化方法 十大接口序列化总结 单查群查 单增群增 单删群删 单整体改/群整体改 单局部改/群局部改 群增群改配置 十大接口小结 字段提供就校验,不提供拉到 DjangoORM内置优化机制:一次最多查21条数据 models.py response.py serializers.py

DRF之视图家族

一:GenericAPIView (1)特点: (1)其继承APIVies,使用完全兼容APIView (2)其在APIView之上又添加了新的功能 (2)使用方式 (3)单取 # 路由层 urlpatterns = [ url(r'^v2/books/$', views.BookGenericAPIView.as_view()), url(r'^v2/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()), ] # 视图层def ge

drf的视图家族

一.昨日内容复习 """ 1.(重点)二次封装Response:自定义APIResponse继承Response,重写__init__方法 2.(正常)设置了abstract为True的模型类,称之为基表,这样的模型类是专门作为基类来提供公有属性的序列 3.(重点)ORM多表关联操作: 外键所放位置 一对多:外键放在多的一方 多对多:外键放在常用的一方 一对一:外键放在不常用的一方 外键字段为正向查询字段,related_name是反向查询字段 外键如何断关联 设置外键字段d

Django之路由层

Django之路由层 一 路由的作用 路由即请求地址与视图函数的映射关系,如果把网站比喻为一本书,那路由就好比是这本书的目录,在Django中路由默认配置在urls.py中,如下图: 二 简单的路由配置 # urls.py from django.conf.urls import url # 由一条条映射关系组成的urlpatterns这个列表称之为路由表 urlpatterns = [ url(regex, view, kwargs=None, name=None), # url本质就是一个函

Django rest-framework视图家族

目录 视图家族 视图类 GenericAPIView APIView GenericAPIView 使用GenericAPIView类 视图工具类 mixins 五大工具类 六大工具方法 使用mixins的六大工具方法 工具视图类 generics 使用generics的工具类实现接口 视图集 viewsets 使用viewsets的视图集类实现接口 完善viewsets的视图集类实现接口 实现群增,群整体改,群局部改,群删四个接口 实现删除只做字段的修改 实现返回信息包含数据状态码和状态信息