DRF框架学习(三)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 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配置的时候指定请求地址请求方式和处理函数之间的对应的关系。

相关文章
|
6月前
|
Python API 网络架构
Django实践-10RESTful架构和DRF入门
Django实践-10RESTful架构和DRF入门
Django实践-10RESTful架构和DRF入门
|
3月前
|
JSON API 网络架构
Django 后端架构开发:DRF 高可用API设计与核心源码剖析
Django 后端架构开发:DRF 高可用API设计与核心源码剖析
69 0
|
5月前
|
JSON 前端开发 API
Django API开发实战:前后端分离、Restful风格与DRF序列化器详解
Django API开发实战:前后端分离、Restful风格与DRF序列化器详解
|
6月前
|
缓存 API 数据库
构建高效Python Web应用:Flask框架与RESTful API设计原则
【5月更文挑战第20天】 在现代Web开发中,构建一个轻量级且高效的后端服务至关重要。本文将深入探讨如何使用Python的Flask框架结合RESTful API设计原则来创建可扩展和易于维护的Web应用程序。我们将通过分析Flask的核心特性,以及如何利用它来实现资源的合理划分、接口的版本控制和请求处理优化等,来指导读者打造高性能的API服务。文中不仅提供了理论指导,还包括了实践案例,旨在帮助开发者提升开发效率,并增强应用的稳定性和用户体验。
|
6月前
|
前端开发 API 网络架构
Python 如何开发出RESTful Web接口,DRF框架助力灵活实现!
Python 如何开发出RESTful Web接口,DRF框架助力灵活实现!
105 0
|
JSON 前端开发 数据安全/隐私保护
DRF框架学习(四)
DRF框架学习(四)
|
JSON 前端开发 API
DRF框架学习(一)
DRF框架学习(一)
|
JSON API 数据库
DRF框架学习(二)
DRF框架学习(二)
|
JSON 前端开发 Android开发
DRF框架使用时的一些注意点
DRF框架使用时的一些注意点
|
JSON API 数据库
下一篇
无影云桌面