首页 > 编程语言 >Restful规范,序列化和反序列化,drf介绍,drf之APIView源码分析

Restful规范,序列化和反序列化,drf介绍,drf之APIView源码分析

时间:2023-05-16 19:56:12浏览次数:40  
标签:api self request drf 源码 https 序列化 view

Restful规范:

  -RESTful是一种定义API接口的设计风格,AIP接口的编写规范,,尤其适用于前后端分离的应用模式中

  -这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源

  -我们可以使用任何一个框架都可以实现符合restful规范的API接口

  Restful10条规范:

    1 数据的安全保障,通常使用https协议进行传输

    2 url地址中带接口标识:一般这样:

       -https://api.baidu.com

       -https://www.baidu.com/api

    3 多版本共存,url地址中带版本信息
       -https://api.baidu.com/v1/login/
       -https://api.baidu.com/v2/login/

    

    4 数据即是资源,均使用名词:
      url地址尽量使用名词
      接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
        https://api.baidu.com/users
        https://api.baidu.com/books
        https://api.baidu.com/book
      注:一般提倡用资源的复数形式,在url链接中不要出现操作资源的动词,错误示范:https://api.baidu.com/delete-user

      # 特殊的接口可以出现动词,因为这些接口一般没有一个明确的资源,或是动词就是接口的核心含义
        https://api.baidu.com/place/search
        https://api.baidu.com/login

    5 资源操作由请求方式决定
      #操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查动作
        https://api.baidu.com/books - get请求:获取所有书
        https://api.baidu.com/books/1 - get请求:获取主键为1的书
        https://api.baidu.com/books - post请求:新增一本书书
        https://api.baidu.com/books/1 - put请求:整体修改主键为1的书
        https://api.baidu.com/books/1 - delete请求:删除主键为1的书

    6 url地址中带过滤条件 ?后带过滤条件
        https://api.baidu.com/books -get请求表示查询所有图书,要查名字中有红的图书
        https://api.baidu.com/books?name_contains=红
        https://api.example.com/v1/zoos?limit=10:指定返回记录的数量
        https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置
        https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数
        https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
        https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件

    7 响应状态码(http响应中带状态码)
        -http的响应状态码:https://blog.csdn.net/meng2lin/article/details/128955775
          -1xx:请求正在处理
          -2xx:请求成功 200 201
          -3xx:重定向
          -4xx:客户端错误
          -5xx:服务的错误
          -http的响应的数据中带状态码(公司自己规定的)
          -{code:100}

    8 返回的数据中带错误信息:
      {code:101,msg:用户名或密码错误}
      {code:100,msg:成功}

    9 返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范
      GET /books:返回资源对象的列表(数组)
        -[{name:武松打虎,price:88},{name:西游记,price:88}]
        -{code:100,msg:成功,data:[{name:武松打虎,price:88},{name:西游记,price:88}]}
      GET /books/1:返回单个资源对象
        -{name:武松打虎,price:88} ---{code:100,msg:成功,data:{name:武松打虎,price:88}}
      POST /books:返回新生成的资源对象
        -{id:4,name:武松打虎,price:88} ---{code:100,msg:成功}
      PUT /books/4:返回完整的资源对象
        -{id:4,name:武松打虎,price:188} ---{code:100,msg:修改成功}
      DELETE /books/4: 返回一个空文档 ---{code:100,msg:删除成功}
    10 返回的结果中带url链接

序列化和反序列化:   

    # api接口开发,最核心最常见的一个过程就是序列化
    # 序列化: 把我们识别的数据转换成指定的格式提供给别人。
      例如:我们在django中获取到的数据默认是模型对象(queryset),但是模型对象数据无法直接提供给前端或别的平台使用,所以我们需要把数据进行序列化,变成字符串或者json数据,提供给别人。

    # 反序列化:把别人提供的数据转换/还原成我们需要的格式。
      例如:前端js提供过来的json数据,对于python而言就是字符串,我们需要进行反序列化换成模型类对象,这样我们才能把数据保存到数据库中

    # 序列化:drf称为 read 序列化
    # 反序列化:drf称为 write 反序列化

drf介绍:

    路由层:

from app01.views import BookView
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('books', BookView, 'books')
urlpatterns = [
]
urlpatterns += router.urls

    视图层:

from .serializer import BookSerializer
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    序列化类:

from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

基于APIView的5个接口:

   视图层:

from rest_framework.views import APIView  # APIView继承了djagno原来的View
from .serializer import BookSerializer
from rest_framework.response import Response


class BookView(APIView):
    # 查询所有
    def get(self, request):
        book_list = Book.objects.all()
        # drf提供了序列化类(先别关注)
        ser = BookSerializer(instance=book_list, many=True)  # 序列化
        return Response({'code': 100, 'msg': '成功', 'result': ser.data})

    def post(self, request):
        ser = BookSerializer(data=request.data)  # 反序列化
        if ser.is_valid():  # 数据校验---》有些不合法的禁止
            ser.save()  # 保存到数据库中
        return Response({'code': 100, 'msg': '成功'})


class BookDetailView(APIView):
    # 查询单条
    def get(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book, many=False)  # 序列化
        return Response({'code': 100, 'msg': '成功', 'result': ser.data})

    # 修改一条
    def put(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book, data=request.data)  # 反序列化
        if ser.is_valid():  # 数据校验---》有些不合法的禁止
            ser.save()  # 保存到数据库中
        return Response({'code': 100, 'msg': '成功'})

    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return Response({'code': 100, 'msg': '删除成功'})

    序列化类:

from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

    路由层:

urlpatterns = [
    path('books/', BookView.as_view()),
    path('books/<int:pk>/', BookDetailView.as_view())]

CBV源码分析: 

  最终结论:什么请求方式,就会执行视图类中的什么方法
# cbv写法:
    1 视图中写视图类,继承View,写跟请求方式同名的方法
        class BookView(View):
            def get(self,request):
                return 四件套
     2 在路径用写
        path('books/', BookView.as_view())
        
        
        
# 如上写法,为什么能够执行

# 前置条件:前端请求,一旦路径匹配成功,就会执行  BookView.as_view()(request传入,)
# 入口在  BookView.as_view()--->执行结果---》View中有个as_view类的绑定方法
    @classmethod
    def as_view(cls, **initkwargs):
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            res=self.dispatch(request, *args, **kwargs)
            return res
        return view
    
# 执行结果是view 的内存地址: 请求来了,执行view(request)
    path('books/', view)
    
# 执行 View类中的as_view方法中的内层的view函数,路由匹配成功,本质是在执行
    self.dispatch(request, *args, **kwargs)
    # self是谁的对象?BookView的对象
    # 去BookView中dispatch,找不到,去父类,View中找到了
    
    
# View这个类的dispatch
    def dispatch(self, request, *args, **kwargs):
        # request.method.lower() 如果是get请求,  ‘get’ 在这个列表里面
        if request.method.lower() in self.http_method_names:
            # handler=getattr(BookView的对象,'get')   
            # handler就是BookView类中的get方法
            handler = getattr(self, request.method.lower())
        else:
            handler = self.http_method_not_allowed
        # 执行 BookView类中的get方法 (request)
        return handler(request, *args, **kwargs)
    
# 最终本质跟写fbv的执行流程一样
# 最终结论:什么请求方式,就会执行视图类中的什么方法

APIView执行流程分析:

    总结:
      1 以后只要继承APIView的所有视图类的方法,都没有csrf的校验了
      2 以后只要继承APIView的所有视图类的方法 中的request是新的request了
      3 在执行视图类的方法之前,执行了三大认证(认证,权限,频率)
      4 期间除了各种错误,都会被异常捕获,统一处理

# 有了drf,后期都写CBV,都是继承APIView及其子类
# 执行流程:
    -入口:path('books/', BookView.as_view())---》请求来了,执行BookView.as_view()(request)
    -as_view 是谁的? APIView的as_view
        @classmethod
        def as_view(cls, **initkwargs):
            # super()代指的是:父类对象  View类的对象
            # View的as_view(**initkwargs)----》执行结果是view,是View类的as_view方法中的view
            view = super().as_view(**initkwargs)
            view=csrf_exempt(view)  # 局部禁用csrf,
            return view
        
      -path('books/', View类的as_view中的view,只是去掉了csrf的认证)
    -请求来了,执行 【View类的as_view中的view,只是去掉了csrf的认证(request)】
    -执行:self.dispatch(request, *args, **kwargs),  self要从根上找
    -self.dispatch 是APIView的dispatch,源码如下
        def dispatch(self, request, *args, **kwargs):
            # request 是新的request,      request是老的request
            request = self.initialize_request(request, *args, **kwargs)
            self.request = request
            try:
                # 执行了认证,权限和频率
                self.initial(request, *args, **kwargs)
                # 在执行视图类方法之前,去掉了csrf认证,包装了新的request,执行了认证频率和权限
                #### 执行请求方式字符串对应的方法
                if request.method.lower() in self.http_method_names:
                    handler = getattr(self, request.method.lower(),
                                      self.http_method_not_allowed)
                else:
                    handler = self.http_method_not_allowed
                response = handler(request, *args, **kwargs)
            except Exception as exc:
                response = self.handle_exception(exc)
                
            # 无论是在三大认证,还是视图类的方法中,出现错误,都会被异常捕获,统一处理
            self.response = self.finalize_response(request, response, *args, **kwargs)
            return self.response
    

 

标签:api,self,request,drf,源码,https,序列化,view
From: https://www.cnblogs.com/Hao12345/p/17406639.html

相关文章

  • Rocky 9 Linux 平台 vim 9.0 源码包编译安装踩坑记录
    目录vim9.0部署准备环境vim9.0源码包正式部署vim9.0初体验plug-vim安装插件在上一篇《vim入门实战》篇,我并没有介绍Linux平台源码包形式安装以及基础运用。本篇教程,以源码包形式部署vim9.0,演示RockyLinux9平台安装vim9.0.1523,目前最新版为vim9.0.15xx。如......
  • Restful规范,drf安装和介绍和使用,APIView源码分析
    1Restful规范#RESTful是一种定义API接口的设计风格,AIP接口的编写规范,,尤其适用于前后端分离的应用模式中这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源我们可以使用任何一个......
  • 看源码技巧
    1.利用好idea的debug功能2.不要避重就轻,就是说先通读快读代码, 建立整体的概念,理解某个方法内重要的步骤有哪些,分成大块儿总结出来(不要一上来就一行一行的仔细看, 源码通常都很多很深, 一行行的看, 看到猴年马月)3.可以把代码粘出来,不重要的代码先该删的删掉,......
  • Angular ngZone 源码解析
    AngularngZone源码解析ngZone源码中有几个常用的方法,属性,这里做一个整理与总结Zone.js简介ZoneJs职责拦截异步任务的调度封装回调函数用于异常处理以及异步操作中zone的跟踪提供往zone中添加数据的方法提供上下文特定的最后一帧错误处理拦截阻塞方法Zone的底层异......
  • Spring源码:Bean生命周期(五)
    前言在上一篇文章中,我们深入探讨了Spring框架中Bean的实例化过程,该过程包括从Bean定义中加载当前类、寻找所有实现了InstantiationAwareBeanPostProcessor接口的类并调用实例化前的方法、进行实例化、调用applyMergedBeanDefinitionPostProcessors方法等多个步骤,最终生......
  • 08-接口自动化框架-源码
     原文链接:https://www.cnblogs.com/xiehong/p/14841538.html前言:以前弄过好多接口自动化框架的东西,比如httprunner2.0版本实现的接口自动化框架,还有httprunner3.X实现的接口自动化框架,这些都是开源的,实现起来比较简单。以及使用python+unittest+ddt+yaml等工具实现的接口自动......
  • app直播源码,css宽度不固定,水平居中
    app直播源码,css宽度不固定,水平居中1.相对定位:  #box{position:relative;left:50%;float:left;} #inner{position:relative;left:-50%;} ​需考虑浮动带来的问题 2.利用diplay:table来解决: #box{display:table;margin:0auto}/*不支持ie6,ie7*/  3.CSS3fl......
  • 直播系统app源码,滑块效果、slider用法
    直播系统app源码,滑块效果、slider用法    <viewclass="selconbox">    <viewclass="seltit">购买力</view>    <viewclass="progressbox">     <viewclass="zijintit"wx:if="{{price==0}}......
  • pmsm电阻电感磁链常数辨识源码 电阻,电感,磁链常数辨识。 程序
    pmsm电阻电感磁链常数辨识源码电阻,电感,磁链常数辨识。程序在tidsp实现。在ti开源foc框架基础上开发。能够辨识电机电阻,电感,磁链常数。精度较高,能够满足foc控制需要。辨识时间短,大约两秒完成电阻电感辨识。磁链辨识需要电机旋转。多次辨识,结果一致性好。辨识部分代码不包含寄存......
  • 基于STM32F407/STM32H743芯片和SOEM的E therCAT主站源码 提供配套CUBE工程和。
    基于STM32F407/STM32H743芯片和SOEM的EtherCAT主站源码提供配套CUBE工程和。可配套正点原子探索者开发板使用,或任何带以太网口的407/H743板子。支持DC同步。可配合汇川IS620N、埃斯顿ProNet、迈信EP3E、台达A2-E、伟创SD700、松下A5B/A6B和欧姆龙G5系列驱动器使用,或提供想适配的......