• 12 drf精华总结


    1.restful10条规范

    # 10条规范
    1  数据的安全保障:url链接一般都采用https协议进行传输 注:采用https协议,可以提高数据交互过程中的安全性
    2 接口特征表现,一看就知道是个api接口
        - 用api关键字标识接口url:
          - [https://api.baidu.com](https://api.baidu.com/)
          - https://www.baidu.com/api
          注:看到api字眼,就代表该请求url链接是完成前后台数据交互的
          -路飞的接口:https://api.luffycity.com/api/v1/course/free/
    3 多数据版本共存
        - 在url链接中标识数据版本
        - https://api.baidu.com/v1
        - https://api.baidu.com/v2
        注:url链接中的v1、v2就是不同数据版本的体现(只有在一种数据资源有多版本情况下)
    4 数据即是资源,均使用名词(可复数)
        - 接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
          - 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 资源操作由请求方式决定(method)
        - 操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查动作
          - 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 - patch请求:局部修改主键为1的书
          - https://api.baidu.com/books/1 - delete请求:删除主键为1的书
    6 过滤,通过在url上传参的形式传递搜索条件
        - 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 响应状态码
       7.1 正常响应
        - 响应状态码2xx
          - 200:常规请求
          - 201:创建成功
       7.2 重定向响应
        - 响应状态码3xx
          - 301:永久重定向
          - 302:暂时重定向
       7.3 客户端异常
        - 响应状态码4xx
          - 403:请求无权限
          - 404:请求路径不存在
          - 405:请求方法不存在
    	7.4 服务器异常
        - 响应状态码5xx
          - 500:服务器异常
     8 错误处理,应返回错误信息,error当做key
        {
            error: "无权限操作"
        }
        
     9 返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范
        GET /collection:返回资源对象的列表(数组)
        GET /collection/resource:返回单个资源对象
        POST /collection:返回新生成的资源对象
        PUT /collection/resource:返回完整的资源对象
        PATCH /collection/resource:返回完整的资源对象
        DELETE /collection/resource:返回一个空文档
        
     10 需要url请求的资源需要访问资源的请求链接
         # Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么
            {
                "status": 0,
                "msg": "ok",
                "results":[
                    {
                        "name":"肯德基(罗餐厅)",
                        "img": "https://image.baidu.com/kfc/001.png"
                    }
                    ...
                    ]
            }
    

    2 django上写符合restful规范的接口

    3 drf写接口

    4 APIView--》继承了原生View---》get,post方法

    	-(为什么get请求来了,就会执行get方法:原生View的dispatch控制的)
        -路由配置:视图类.as_view()---->view(闭包函数)的内存地址
        -请求来了,就会执行view(requst,分组分出的字段,默认传的字段)---》self.dispatch()-->处理的
        
        -APIView重写了dispatch:包装了request对象,解析器,分页,三大认证,响应器,全局异常,去掉了csrf
    

    5 Request对象

    request._request,request.data,重写了__getattr__,request.method-->去原生request中拿
    	-前端传过来的数据从那取?
        	-地址栏里:request.GET/query_params
           	-请求体中的数据:request.data/POST(json格式解释不了)---》request.body中取
            -请求头中数据:request.META.get("HTTP_变成大写")
    

    6 Response对象

    封装了原生的HttpResponse,Response(data,headers={},status=1/2/3/4/5开头的)
    

    7 自定义Response对象

    8 序列化类

    	-Serializer
        	-写字段,字段名要跟表的字段对应,想不对应(source可以修改),有属性,read_only,max_len...
            -SerializerMethodField必须配套一个get_字段名,返回什么,前台就看到什么
        -ModelSerializer
        	-class Meta:
            	表对应
                取出的字段(__all__,列表)
                排除的字段(用的很少)
                extra_kwargs会给字段的属性
                
            -重写某个字段
            	password=serializers.SerializerMethodField()
                def get_password(self,instance):
                    return "***"
            -校验:字段自己的校验,局部钩子,全局钩子
            	-只要序列化类的对象执行了is_valiad(),这些钩子都会走,可以再钩子里写逻辑
            -在表模型(model)中写方法,可以在上面取出的字段中直接写,不参与反序列化
       -序列化多条(many=True):本质,ListSerializer内部套了一个个的serializer对象
       -重写ListSerializer,让序列化对象和自己写的ListSerializer对应上(了解)
    	-序列化类(instance,data,many,context={requtst:request})
    	-视图函数中给序列化对象传递数据,使用context,传回来,放进去直接使用序列化对象.context.get()
    

    9 视图

    	-两个视图基类 APIView,GenericAPIView(继承APIView):涉及到数据库和序列化类的操作,尽量用GenericAPIView
        -5个视图扩展类(父类都是object)
            CreateModelMixin:create
            DestroyModelMixin:destory
            ListModelMixin
            RetrieveModelMixin
            UpdateModelMixin
        -9个视图子类(GenericAPIView+上面5个视图扩展类中的一个或多个)
        	RetrieveUpdateDestroyAPIView
            CreateAPIView
            RetrieveAPIView
            DestroyAPIView
            RetrieveUpdateAPIView
            ListCreateAPIView
            UpdateAPIView
            ListAPIView
            RetrieveDestroyAPIView
        -视图集
        	-ModelViewSet:5大接口都有了
            -ReadOnlyModelViewSet:获取一条和获取多条的接口
        	-GenericViewSet:ViewSetMixin+GenericAPIView        
            ViewSet:ViewSetMixin+APIView
            ViewSetMixin:类重写了as_view,路由配置就变样了
    

    10 路由

    -基本配置:跟之前一样
        -有action的:必须继承ViewSetMixin
        -自动生成:DefaultRouter和SimpleRouter
        	-导入,实例化得到对象,注册多个,对象.urls(自动生成的路由)
            -路由相加urlpatterns+=router.urls/include:path('', include(router.urls))
        -视图类中自己定义的方法,如何自动生成路由
        	-在自己定义的方法上加装饰器(action)
            -两个参数methods=[GET,POST],表示这两种请求都能接受
            -两个参数detail=True,表示生成带pk的连接
    

    11 三大认证

    -认证组件:校验用户是否登录
        	-写一个认证类,继承BaseAuthentication,重写authenticate,内部写认证逻辑,认证通过返回两个值,第一个是user,认证失败,抛去异常
            -全局使用,局部使用,局部禁用
        -权限:校验用户是否有权限进行后续操作
        	-写一个类,继承BasePermission,重写has_permission,True和False
            -全局使用,局部使用,局部禁用
        -频率:限制用户访问频次
        	-写一个类,继承SimpleRateThrottle,重写get_cache_key,返回什么,就以谁做限制,scop=luffy字段,需要跟setting中的key对应   luffy:3/h(一小时访问三次)
            
            -全局配置,局部配置,局部禁用
            -需求:发送短信验证码的接口,一分钟只能发送一次,局部使用,配在视图类上
    

    12 解析器

    前端传的编码格式,能不能解析(默认三种全配了,基本不需要改),可能你写了个上传文件接口,局部配置一下,只能传form-data格式  局部使用:MultiPartParser
    

    13 响应器

    响应的数据,是json格式还是带浏览器的那种(不需要配)

    14 过滤器

    借助于第三方django-filter

    -注册应用
        -setting中配置DjangoFilterBackend或者局部配置
        -filter_fields = ('age', 'sex')
    

    15 排序

    	-全局或者局部配置rest_framework.filters.OrderingFilter
        -视图类中配置: ordering_fields = ('id', 'age')
    

    16 分页

    -使用:
            继承了APIView的视图类中使用
            	 page=Mypage()
                # 在数据库中获取分页的数据
                page_list=page.paginate_queryset(queryset对象,request,view=self)
                # 对分页进行序列化
                ser=BookSerializer1(instance=page_list,many=True)
                # return Response(ser.data)
            继承了视图子类的视图中使用
            	 pagination_class = PageNumberPagination(配置成自己重写的,可以修改字段)
    	-CursorPagination
            cursor_query_param:默认查询字段,不需要修改
            page_size:每页数目
            ordering:按什么排序,需要指定
    	-LimitOffsetPagination
        	default_limit 默认限制,默认值与PAGE_SIZE设置一直
            limit_query_param limit参数名,默认’limit’
            offset_query_param offset参数名,默认’offset’
            max_limit 最大limit限制,默认None
    	-PageNumberPagination:最常用的,需要在setting中配置page_size,四个参数
            page_size 每页数目
            page_query_param 前端发送的页数关键字名,默认为”page”
            page_size_query_param 前端发送的每页数目关键字名,默认为None
            max_page_size 前端最多能设置的每页数量
    

    17 全局异常

    -写一个方法
        	def exception_handler(exc, context):
                # 走drf原来的异常,原理异常有一些处理
                response = drf_exception_handler(exc, context)
    			# 我们自己处理,drf没有处理,丢给django的异常
                if response is None:
                    if isinstance(exc, DatabaseError):#处理了一下数据库错误
                        response = Response({'detail': '数据库错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)
                    else:#其他异常
                        response = Response({'detail': '未知错误'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
        return response
        -配置文件中配置(以后所有drf的异常,都会走到这里)
        	REST_FRAMEWORK = {
                'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
            }
            
    

    18 jwt

    -是什么json web token  新的认证方式
        -三段:头,荷载(用户信息),签名
        -使用:最简单方式(在路由中配置)
        	-path('login/', obtain_jwt_token),
        -自定制:
        	多方式登录,手动签发token(两个方法)
        -自定制基于jwt的认证类
        	-取出token
            -调用jwt提供的解析出payload的方法(校验是否过期,是否合法,如果合法,返回荷载信息)
            -转成user对象
            -返回
            
      -19 RBAC:基于角色的权限控制(django默认的auth就是给你做了这个事),公司内部权限管理
    		对外的权限管理就是用三大认证
    	-用户表
        -用户组表
        -权限表
        -用户对用户组中间表
        -用户组对权限中间表
        -用户对权限中间表
    
  • 相关阅读:
    1295: [SCOI2009]最长距离
    [vijos p1028] 魔族密码
    HJ浇花
    1060: [ZJOI2007]时态同步
    1816: [Cqoi2010]扑克牌
    1800: [Ahoi2009]fly 飞行棋
    4300: 绝世好题
    1237: [SCOI2008]配对
    1801: [Ahoi2009]chess 中国象棋
    1189: [HNOI2007]紧急疏散evacuate
  • 原文地址:https://www.cnblogs.com/bailongcaptain/p/13323610.html
Copyright © 2020-2023  润新知