Restframe_work 回顾记忆集

Restframe_work 回顾记忆集

     rest_framework是一个基于django的框架,可以看作是django的第三方库,库提供最基础功能就是方便开发restful接口。同时该第三方库,也是实现了django app的环境(或者说该库是以django app方式封装的一个package),可以作为app注册到django项目中,提供一些已经完成好的web应用功能(如登录API功能,提供基于token的身份认证及其model等,减少业务上重复开发业务逻辑)。
      rest_framework作为django的三方库(或者叫django生态中的组件), 提供了很多模块。
记忆集会遇到更新

rest_framework主要功能介绍

可以大致对应下面将要提到的"主要模块介绍" :

  1. 丰富的视图类,为其它功能提供嵌入使用的基础环境。
  2. 厉害的序列化类, 提供将python对象(包括model对象),按照序列化类定义字段,且以这些定义的字段为迭代条件,来对python对象的同名字段属性进行处理。如果python对象的同名属性对应的还是一个复杂数据对象(如列表,还可以对列表中的元素做序列化处理,这叫child field)。序列化类的目的是,能够将不可序列化对象转换为python的可序列化对象(说白就是将对象转化为字典),提供输出转换结果的接口(即Serializer.data)。然后即可以对这个结果进行真正的序列化为可磁盘化类型(json字符串)。序列化类依照定义还可以反向,也是按照定义字段,将字典相同key名的数据,反序列化为相同名字的字段定义的类型数据。最后得到Serializer.validation_data就是反序列化且校验过约束条件后的数据。校验也是序列化类提供的重要功能。小结就是:序列化类提供 序列化/校验/反序列化 三大功能。
  3. 多彩的渲染类,可以自定义接口调用响应的内容渲染为什么格式(html模版、json、xml等等)。rest_framework内置供了一些渲染类。使用渲染类到View中,通过FBV通过装饰器,CBV通过render_classes=[] 插入。
  4. 聪明的内容协商类, 该类提供了根据请求来决定使用上面哪个类来展示渲染响应内容。默认是negotiation.DefaultContentNegotiation类。
  5. 兼容的版本类,提供多种版本url设计版本方案。查询参数、urlpath、httprequest header等。对于urlpath是restful推荐的,这里通过有名分组,将版本信息带入到view函数中,并获取到版本信息。
  6. 明确的认证类,明确登录用户和其id token。
  7. 安全的权限类,提供访问权限鉴别。
  8. 主动防御的频率器类,访问流量大小限制。
  9. 友好的分页器类, 提供分页查询。
  10. 自动化的路由类,基于ViewSet自动化生成符合常用业务逻辑的路由。对于通过装饰器额外增加的actions,自动化生成动态的路由的url会在默认url后加上方法名(当然也可以自定义actions的追加的url名字。参考官网https://www.django-rest-framework.org/api-guide/routers/#routing-for-extra-actions)。
  11. 方便的解析器类, 用于解析我们的请求体,依据正确的编码方式。常用parsers.JSONParser/FormParser/MultiPartParser/FileUploadParser.将解析为对应的python数据类型,提供我们操作访问。

rest_framework主要模块介绍

  • views 模块,提供CBV类:APIView
  • mixins 模块,提供实现了各种actions操作。但是要结合generics模块中的方法。里面实现了各种actions都是为了符合常用的restful架构常见业务逻辑动作。
  • generics 模块,首先提供了GenericAPIView为mixins模块中的业务动作提供方法。再者,该模块还提供了组合业务封装类,即是将mixins中的actions组合起来,放入一个类中,用于对应的CBV restful风格业务中(这种组合,能够很好对应上restful 面向资源,方法即操作的思想,也将当个资源和资源集的不同操作actions进行划分)。
  • viewsets 模块, 将业务操作actions整合到一个类中,所以叫做“视图集合”。由于将actions都放到了一个类中集合起来,那么基于这种封装,产生更高级和更方便的功能模块那么就是routers模块。viewsets模块能将所有actions放入一个结合中,是因为在使用该这类CBV时,要提供方法和actions的映射关系,用于将对应的actions映射到对应method。而且要指出参数。如果自定义actions还要使用到decorators装饰器模块,来封装我们自定义的actions。所以viewsets是更高级用法的基础。
  • routers 模块,基于viewsets的CBV的模块。通过routers模块,可以将我们urlpattern配置工作自动化(这种自动化也是有模式的,模式就是按照常用业务路由模式来自动化生成的),当然也可以自动化路由。
  • serializers 模块, 提供将python对象按照其属性进行序列化为字典或者列表类型,这些基础类型可以再次序列化为如json等字符串。除了序列化还提供反序列化功能,反序列化功能我个人感觉更重要,反序列化工序更加复杂,所以觉得更重要。反序列化即提供了数据校验的功能,只有校验成功的数据才可以成功的反序列化为python数据类型。校验功能输出校验正确数据和校验错误信息,校验错误信息就可以返回给client端了。由于我们django的数据模式大多是model对象,所以序列化和反序列化django model对象就更加复杂。就牵扯出ModelSerializer序列化类。该类会有更加复杂的处理逻辑,要关联django models模块,这部分处理逻辑就被解耦到了其它模块中,如fields和relations模块中。
  • fields 模块,提供Serializer类的字段类,其实serializers模块提供的字段类,其实都是rest_framework.fields模块中提供的。
  • relations 模块, 提供ModelSerializer类有关字段,这些字段都是表示数据关联其它数据的字段。有句话说的好:“Bad programmers worry about the code. Good programmers worry about data structures and their relationships.” 所以,relations模块关注的就是django model对象件的关系字段。根据restful风格最佳实践,关联的数据对象,可以使用link方式代表关联资源(因为资源数据关联一般都是已主键的方式关联),所以有关Hyperlink字段也放在了relations模块中,毕竟hyperlink表示的也是关系。
  • renderers 模块, 提供了很多的的渲染器类。
  • negotiation 模块, 提供内容协商逻辑,选择出一种渲染类来渲染响应内容。
  • 其它模块略,看官网

记忆集

错题集

  1. 对于HyperlinkedRelatedField ,如果在url种使用version,使用了include.这些都是要特别注意的,不然就会报错不能反解析"django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name ..." 错误,这种情况,就必需要对该字段的view_name中加上app namespace,所以就成了view_name='app_name: url_name'。对于include是解决了,还有一个就是version,如果使用了version,那么version就必须在view视图类中加上versining_classs = URLversionclass ,这样在反解url时才会带上对应请求的version了。被这个问题困扰了一下午。 最后总结,还是少在rest_framework中使用include,避免带来诸多不便。还有就是version,用来就要设置到全局去,这样才能正确使用。查看官网

混淆集

  1. python中可序列化数据类型不只是字符串,数字,列表,字典,orderdict这些也是可序列化的。Serializer.data 有种返回就是OrderedDict字典。
  2. 尽然将CBV中定制render 设置为parser了,将 渲染器和解析器 的参数render_classes 和 parser_classes 弄混淆了

重点集

  1. 使用序列化类,作用对象无论是python对象还是字典,属性名或字典key一定要和序列化类定义的字段名相同。不然序列化类中没有或者缺少序列化类定义的字段会得到没有完整的序列化数据或报错。
  2. 所有的RelatedField的目的对象都是onetoone的object,或者FK的object,要不就是反向FK或者manytomany的related_manger。
  3. 查看ManyRelatedField.get_attribute处理related_manager的处理逻辑。

难点集

  1. ModelSerializer是怎么处理Model的关联字段的。在序列化和反序列化及校验方面。

    这得查看rest_framework的serializers模块的ModelSerializer对象的源码了。
         首先,我们都知道plain Serializer对象,在序列化plain python object的时候,就是循环其属性,然后将属性名字和plain Serializer对象名字相同的,进行对应的序列化与反序列化逻辑。
         次前提, 知道在Serializer类定义时,是可以对一个field定义子字段的。WTF! 字段这么还有子字段嵌套这种概念啊!这是怎么回事呢?其实就是外层一个字段是一个序列化类,用于序列化这个字段对应的对象。
         然而, 对于Model Serializer对象,其实序列化时,遍历的是model object对象的字段属性,对应model object的plain field就根据一个映射字典,找到对应的plian serializer field就可以了。而对应model object的 one-to-one / many-to-many / foreignkey 字段,都归为 serializer的 PrimaryKeyRelateField了。由于one-to-one 和 foreignkey都是有实际字段,字段序列化后都是一个值;而many-to-many是多对多,虚拟化后的字段就是要包含多个值的,所以一般序列化后都是一个字典。所以在使用PrimaryKeyRelateField参数many要设置为True.代表该字段是一个多对多字段。这是要校验和序列化就需要看作是复合字段的方式,就是对于复合数据中的,单个元素看作一个子字段进行序列化和校验了(指定子字段就是使用child参数在父field实例化参数中)。关于多对多字段的PrimaryKeyRelateField会被显示强制转换为包含child字段的ManyRelateField字段。源码中文档英文说明:Restframe_work 回顾记忆集
    也就是说,ManyRelatedField在序列化时,会迭代出对象,然后再将对象使用child原始序列化对象进行序列化。
         最后,源码类关系比较复杂,设计Field,BaseSerializer,Serializer,ModelSerializer和他们其中的方法。注意方法调用的是哪个类中的。

  2. 再次强点rest_framework的序列化类可以说是非常非常重要。对于每一个字段类型,可以大致分为两类: readable_fields 和 writable_fields 即 可序列化和可反序列化,当然有些字段是可以序列化也可以反序列化的。每一个field字段,的readable与writable是根据

上一篇:杭电oj 3361


下一篇:搭建Vue.js环境,建立一个简单的Vue项目