DRF框架学习(三)

简介: DRF框架学习(三)

DRF框架学习(三)

1.视图

1.1作用

1.控制序列化器的执行(数据检验、数据保存、转换数据(序列化操作))

2.控制数据库的查询操作。

1.2类视图的两个基类

1.2.1APIView

是View类的子类,在view类的基础上添加了一些额外的功能。

功能

1.视图中的request对象不再是Django中 HttpRequest类的对象,而是由DRF框架封装成的 Request类的对象。

2.响应时可以统一返回Response类的对象

3.异常处理:如果视图中抛出了未处理异常,DRF框架会自动对异常进行处理,并且会把处理之后的错误信息返回给客户端。例如 Http404这个系统处理过的处理异常的方法,我们直接将它抛出,客户端就可以收到处理之后的错误信息,不会是404页面,而是错误信息,如“未找到“。

4.高级功能:

1)认证

2)权限

3)限流

Request类的对象

1. request.data里面保存解析之后的请求体数据,并且已经解析成了字典或类字典,相当于包含了Django原始request对象中的 request.body|request.POST|request.FILES

2. query_params:保存解析之后的查询字符串数据,并且已经解析成了字典或类字典。 request.query_params与Django标准的 request.GET相同,只是更换了更正确的名称而已。

Response类的对象

1.传入原始相应数据(比如一个字典),Response会自动根据客户端请求头中 Accept将相应数据转换为对应的格式进行返回。默认是json格式。也可以指定返回的是网页,只需要将Accept设置为 text/html即可。但是仅仅支持json和html两种。

为了方便设置状态码,REST framewrok在 rest_framework.status模块中提供了常用状态码常量,我们直接使用即可。

  1. status = status.HTTP_201_CREATED

上面的就可以指定201状态码了,我们直接写201的话,其他人容易看不懂,我们用常量让人易于理解。

1.2.2GenericAPIView

继承于APIView,是APIView的子类,在APIView的基础上添加操作序列化器和数据库查询的方法。封装的这些方法,我们可以直接使用。

补充知识点

1.类视图对象有一个属性: self.kwargs,它是一个字典,保存的是从url地址中提取的所有命名参数。它的作用:比如我们定义了一个视图,没有形参接收传递的参数,那么我们可以使用 self.kwargs从url地址中提取我们需要的数据。

2. queryset指定当前视图所使用的查询集;

serializer_class指定当前视图所使用的序列化器类;

self.serializer_class获取当前视图所使用的序列化器类;

serializer_cls=self.get_serializer_class()获取当前视图所使用的序列化器类;

serializer_cls(*args,**kwargs)创建一个序列化器类对象。

  1. # 自定义一个GenericAPIView
  2. classMyGenericAPIView(APIView):
  3.    queryset =None
  4.    serializer_class =None

  5.    lookup_field ='pk'
  6.    lookup_url_kwarg ='pk'

  7.    def get_serializer_class(self):
  8.        return self.serializer_class
  9.    def get_serializer(self,*args,**kwargs):
  10.        serializer_cls = self.get_serializer_class()
  11.        return serializer_cls(*args,**kwargs)
  12.    def get_queryset(self):
  13.        return self.queryset.all()
  14.    def get_object(self):
  15.        #从视图所使用的查询集中获取指定的对象,默认根据pk进行查询
  16.        # 获取当前视图所使用的查询集
  17.        query_set = self.get_queryset()# QuerySet
  18.        # filters = {'pk':self.kwargs['pk']}
  19.        filters ={self.lookup_field:self.kwargs[self.lookup_url_kwarg]}
  20.        try:
  21.            # obj = query_set.get(pk=self.kwargs['pk])
  22.            obj = query_set.get(**filters)
  23.        exceptException:
  24.            raiseHttp404
  25.        return obj

操作序列化器

a)属性

serializer_class指定当前视图所使用的序列化器类。

b)方法

get_serializer创建一个视图所使用序列化器类的对象。

get_serializer_class返回当前视图所使用的序列化器类。

数据库查询

a)属性

queryset(指定视图所使用的查询集)

b)方法

get_queryset获取当前视图所使用的查询集。

get_object从视图所使用的查询集中查询指定的对象,默认根据pk(查询)进行查询。

其他功能:

a)过滤

b)分页

补充知识点

查询的时候我们想不根据主键pk查询,而是根据我们的需求查,那么可以根据修改 lookup_field(值改为我们要查询的字段的名称)的值来解决需求。

lookup_url_kwarg指定从查询集获取对象时,从url地址中提取的参数的名称。

注意:经常配合Minxin扩展类来使用。

1.3Mixin扩展类(重要)

  1. classMyListModelMixin(object):
  2.    def list(self,request,*args,**kwargs):
  3.        """获取一组数据的通用代码"""
  4.        .....
  5. classMyCreateModelMixin(object):
  6.    def create(self,request,*args,**kwargs):
  7.        """创建一条数据的通用代码"""
  8.        ...
  9. classMyRetrieveModelMixin(object):
  10.    def retrieve(self,request,*args,**kwargs):
  11.        """获取指定的对象数据的通用过程"""

自己抽取代码实现扩展类的步骤:

1)先将通用的代码抽取出来。

2)创建一个扩展类,将抽取的代码进行封装。

3)在原视图函数中进行调用。

1.3.1扩展类5个详解

DRF框架提供了5个扩展类,封装了通用增删改查的流程。

1.3.1.1ListModelMixin

列表视图扩展类,提供 list(request,*args,**kwargs)方法快速实现列表视图,返回200状态码。

该Mixin的list方法会对数据进行过滤和分页。

源代码:

  1. classListModelMixin(object):
  2.    """
  3.    List a queryset.
  4.    """
  5.    def list(self, request,*args,**kwargs):
  6.        # 过滤
  7.        queryset = self.filter_queryset(self.get_queryset())
  8.        # 分页
  9.        page = self.paginate_queryset(queryset)
  10.        if page isnotNone:
  11.            serializer = self.get_serializer(page, many=True)
  12.            return self.get_paginated_response(serializer.data)
  13.        # 序列化
  14.        serializer = self.get_serializer(queryset, many=True)
  15.        returnResponse(serializer.data)

举例:

  1. from rest_framework.mixins importListModelMixin

  2. classBookListView(ListModelMixin,GenericAPIView):
  3.    queryset =BookInfo.objects.all()
  4.    serializer_class =BookInfoSerializer

  5.    def get(self, request):
  6.        return self.list(request)

1.3.1.2CreateModelMixin

创建视图扩展类,提供 create(request,*args,**kwargs)方法快速实现创建资源的视图,成功返回201状态码。

如果序列化器对前端发送的数据验证失败,返回400错误。

源代码:

  1. classCreateModelMixin(object):
  2.    """
  3.    Create a model instance.
  4.    """
  5.    def create(self, request,*args,**kwargs):
  6.        # 获取序列化器
  7.        serializer = self.get_serializer(data=request.data)
  8.        # 验证
  9.        serializer.is_valid(raise_exception=True)
  10.        # 保存
  11.        self.perform_create(serializer)
  12.        headers = self.get_success_headers(serializer.data)
  13.        returnResponse(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

  14.    def perform_create(self, serializer):
  15.        serializer.save()

  16.    def get_success_headers(self, data):
  17.        try:
  18.            return{'Location': str(data[api_settings.URL_FIELD_NAME])}
  19.        except(TypeError,KeyError):
  20.            return{}

1.3.1.3RetrieveModelMixin

详情视图扩展类,提供 retrieve(request,*args,**kwargs)方法,可以快速实现返回一个存在的数据对象

如果存在,返回200, 否则返回404。

源代码:

  1. classRetrieveModelMixin(object):
  2.    """
  3.    Retrieve a model instance.
  4.    """
  5.    def retrieve(self, request,*args,**kwargs):
  6.        # 获取对象,会检查对象的权限
  7.        instance = self.get_object()
  8.        # 序列化
  9.        serializer = self.get_serializer(instance)
  10.        returnResponse(serializer.data)

举例:

  1. classBookDetailView(RetrieveModelMixin,GenericAPIView):
  2.    queryset =BookInfo.objects.all()
  3.    serializer_class =BookInfoSerializer

  4.    def get(self, request, pk):
  5.        return self.retrieve(request)

1.3.1.4UpdateModelMixin

更新视图扩展类,提供 update(request,*args,**kwargs)方法,可以快速实现更新一个存在的数据对象

同时也提供 partial_update(request,*args,**kwargs)方法,可以实现局部更新。

成功返回200,序列化器校验数据失败时,返回400错误。

源代码:

  1. classUpdateModelMixin(object):
  2.    """
  3.    Update a model instance.
  4.    """
  5.    def update(self, request,*args,**kwargs):
  6.        partial = kwargs.pop('partial',False)
  7.        instance = self.get_object()
  8.        serializer = self.get_serializer(instance, data=request.data, partial=partial)
  9.        serializer.is_valid(raise_exception=True)
  10.        self.perform_update(serializer)

  11.        if getattr(instance,'_prefetched_objects_cache',None):
  12.            # If 'prefetch_related' has been applied to a queryset, we need to
  13.            # forcibly invalidate the prefetch cache on the instance.
  14.            instance._prefetched_objects_cache ={}

  15.        returnResponse(serializer.data)

  16.    def perform_update(self, serializer):
  17.        serializer.save()

  18.    def partial_update(self, request,*args,**kwargs):
  19.        kwargs['partial']=True
  20.        return self.update(request,*args,**kwargs)

1.3.1.5DestroyModelMixin

删除视图扩展类,提供 destroy(request,*args,**kwargs)方法,可以快速实现删除一个存在的数据对象

成功返回204,不存在返回404。

源代码:

  1. classDestroyModelMixin(object):
  2.    """
  3.    Destroy a model instance.
  4.    """
  5.    def destroy(self, request,*args,**kwargs):
  6.        instance = self.get_object()
  7.        self.perform_destroy(instance)
  8.        returnResponse(status=status.HTTP_204_NO_CONTENT)

  9.    def perform_destroy(self, instance):
  10.        instance.delete()

1.3.2子类视图类

1.3.2.1CreateAPIView

  1. 提供 post 方法

  2. 继承自:GenericAPIViewCreateModelMixin

1.3.2.2ListAPIView

  1. 提供 get 方法

  2. 继承自:GenericAPIViewListModelMixin

1.3.2.3RetrieveAPIView

  1. 提供get方法

  2. 继承自:GenericAPIViewRetrieveModelMixin

1.3.2.4DestoryAPIView

  1. 提供 delete 方法

  2. 继承自:GenericAPIViewDestoryModelMixin

1.3.2.5UpdateAPIView

  1. 提供 put patch 方法

  2. 继承自:GenericAPIViewUpdateModelMixin

1.3.2.6ListCreateAPIView

  1. 提供 get post 方法

  2. 继承自:GenericAPIViewListModelMixinCreateModelMixin

1.3.2.7RetrieveUpdateAPIView

  1. 提供 getputpatch方法

  2. 继承自:GenericAPIViewRetrieveModelMixinUpdateModelMixin

1.3.2.8RetrieveDestroyAPIView

  1. 提供 get delete 方法

  2. 继承自:GenericAPIViewRetrieveModelMixinUpdateModelMixin

1.3.2.9RetrieveUpdateDestoryAPIView

  1. 提供 getputpatchdelete方法

  2. 继承自:GenericAPIViewRetrieveModelMixinUpdateModelMixinDestoryModelMixin

公司中如果不知道该继承哪一个类,那么就继承APIView,完成了需求之后我们再进行代码的优化。时间长了之后,就知道该怎么写最简单的代码了。

2.视图集

2.1概念

将操作同一组资源的处理方法(API接口)同一个类中。(重要)

2.2注意点

1、视图集中的处理方法不再是以请求方式命名,而是以对应的操作名称(list、create、update、retrieve、destroy)

2、在进行url配置的时候,要指明请求地址的请求方式和视图集中处理函数之间的对应关系。

2.3视图集父类

ViewSet

  1. 继承自ViewSetMixinAPIView

GenericViewSet

使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写,而这些方法与前面讲过的Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法而无需自己编写。但是Mixin扩展类依赖与 GenericAPIView,所以还需要继承 GenericAPIView

GenericViewSet就帮助我们完成了这样的继承工作,继承自 GenericAPIViewViewSetMixin,在实现了调用as_view()时传入字典(如 {'get':'list'})的映射处理工作的同时,还提供了 GenericAPIView提供的基础方法,可以直接搭配Mixin扩展类使用。

ModelViewSet

  1. 继承自GenericViewSet,同时包括了ListModelMixinRetrieveModelMixinCreateModelMixinUpdateModelMixinDestoryModelMixin

ReadonlyModelViewSet

  1. 继承自GenericViewSet,同时包括了ListModelMixinRetrieveModelMixin

2.4视图集中添加额外的处理方法

1、直接在视图集中定义额外的处理方法即可

2、在进行url配置的时候指定请求地址请求方式和处理函数之间的对应的关系。

相关文章
|
存储 JSON 前端开发
使用JSZip实现压缩文件与图片
使用JSZip实现压缩文件与图片
|
11月前
|
Cloud Native Devops 持续交付
云原生架构的演进与实践
本文深入探讨了云原生架构的核心概念、技术组件及其在现代软件开发中的应用。通过分析容器化、微服务、持续集成/持续部署(CI/CD)等关键技术,揭示了这些技术如何共同促进应用程序的灵活性、可扩展性和高可用性。文章还讨论了云原生架构实施过程中面临的挑战和最佳实践,旨在为开发者和企业提供一套实用的指导方针,以便更有效地利用云计算资源,加速数字化转型的步伐。
251 5
|
开发者 C++
经典面试题:预处理器标识#error的目的是什么
在 C 和 C++ 中,预处理器指令 `#error` 用于在编译时生成错误并终止编译。它主要用于条件编译中的错误检查,如检测缺失的宏定义或不支持的平台;指示已知问题或未实现的功能;防止错误的构建配置;以及生成编译时的显式错误信息以帮助代码维护。通过 `#error`,开发者可以在编译阶段就阻止有问题的代码继续执行,并提供明确的错误信息,从而简化调试过程。
|
安全 数据中心 数据安全/隐私保护
SD-WAN组网场景
【5月更文挑战第14天】SD-WAN旨在实现企业分支、总部、数据中心及云平台间的网络互通,并确保对互联网、SaaS应用和公有云的访问。
|
Java 关系型数据库 MySQL
如何安装系统必备开发环境:JDK 1.8+、MySQL 5.7+ 与 Maven 3.0+
【7月更文挑战第1天】搭建Java开发环境:安装JDK 1.8+,MySQL 5.7+,Maven 3.0+。访问官方源下载对应软件,配置Windows或Linux/macOS的环境变量,包括`JAVA_HOME`, `PATH`, `MYSQL_ROOT_PASSWORD`及`MAVEN_HOME`。测试安装成功分别用`java/javac -version`, `mysql -u root -p`和`mvn -v`检查版本。完成后,即可开始Java项目开发。
955 0
|
存储 JavaScript 前端开发
JavaScript 自定义对象 及 new()原理与实现 如何完整地手写实现new
JavaScript 自定义对象 及 new()原理与实现 如何完整地手写实现new
297 0
【推荐】实现跟随鼠标移动的浮动提示框、气泡框、Tip效果
【推荐】实现跟随鼠标移动的浮动提示框、气泡框、Tip效果
|
存储 算法 数据可视化
MySQL数据库 -- 索引结构 (B+ tree 与 Hash)
索引(index)是帮助MySQL高效获取数据的数据结构 , 在Mysql中有两个最常用的索引 -- B+tree索引 和 Hash索引 B-Tree(B树)是一种多叉路平衡查找树,相对于二叉树,B树每个节点可以有多个分支 哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中
591 0
|
缓存 网络协议 虚拟化
jeasypoi导入excel,数字列导入失败解决办法
jeasypoi导入excel,数字列导入失败解决办法
619 0
jeasypoi导入excel,数字列导入失败解决办法