DRF入门

DRF入门

一 web开发模式

1) 前后端混合开发(模板语言:DTL),处理很多前端问题

2) 前后端分离:前端是一个项目,后端是一个项目,联调
	-全栈开发

3) 前端:不仅仅指 web前端,移动端,小程序
	-web:vue,react,html+css+jq
    -移动端:ios(object c,swift),安卓(java,Kotlin)
    -小程序:微信自己把js,html,css,封装了一些    
    -发展到现在:大前端概念
    	-flutter:Dart
        -uni-app:vue框架
            
4) 后端只需要返回json格式字符串即可

二 API接口

1 关于API接口

1) /books/--->返回json格式数据--->/books/就是一个api接口

2) 开放的api接口
	-微博
    -百度
    
3) api文档(给前端开发看的)

4) 典型的api接口
	-https://api.weibo.com/2/statuses/home_timeline.json

2 Web API接口简单概括有下面四大特点

1)-url:长得像返回数据的url链接
	-https://api.map.baidu.com/place/v2/search

2)-请求方式:get、post、put、patch、delete
    -采用get方式请求上方接口

3)-请求参数:json或xml格式的key-value类型数据
    -ak:6E823f587c95f0148c19993539b99295
    -region:上海
    -query:肯德基
    -output:json

4)-响应结果:json或xml格式的数据
    -上方请求参数的output参数值决定了响应数据的格式

三 接口测试工具:Postman

1) 后端开发完,使用postman测试接口(api接口)
2) 使用postman导出和导入测试接口
3) 公司测试平台

四 Django Rest_Framework

1 什么是DRF

核心思想: 缩减编写api接口的代码

- Django REST framework是一个建立在Django基础之上的Web 应用开发框架,可以快速的开发REST API接口应用。在REST framework中,提供了序列化器Serialzier的定义,可以帮助我们简化序列化与反序列化的过程,不仅如此,还提供丰富的类视图、扩展类、视图集来简化视图的编写工作。REST framework还提供了认证、权限、限流、过滤、分页、接口文档等功能支持。REST framework提供了一个API 的Web可视化界面来方便查看测试接口。

官方文档:https://www.django-rest-framewo  rk.org/

github: https://github.com/encode/django-rest-framework/tree/master        

2 特点及用途

-提供了定义序列化器Serializer的方法,可以快速根据 Django ORM 或者其它库自动序列化/反序列化;
-提供了丰富的类视图、Mixin扩展类,简化视图的编写;
-丰富的定制层级:函数视图、类视图、视图集合到自动生成 API,满足各种需要;
-多种身份认证和权限认证方式的支持;[jwt]
-内置了限流系统;
-直观的 API web 界面;
-可扩展性,插件丰富

五 drf的安装和使用

1) djangorestframework:django的app,只能再django上使用
2) pip3 install djangorestframework
3) 简单使用,看代码
	django: 2.0.7 ,1版本也可以
    djangorestframework:3.12.1

六 RESTful API规范**

1) Representational State Transfer:表征性状态转移
2) Web API接口的设计风格,尤其适用于前后端分离的应用模式中
3) 与语言,平台无关,任何框架都可以写出符合restful规范的api接口
4) 规范:10条
	-1)  数据的安全保障:url链接一般都采用https协议进行传输
    -2)  接口特征表现:api关键字标识
    	-https://api.baidu.com/books/
        -https://www.baidu.com/api/books/
    -3) 多版本共存:url链接中标识接口版本
    	-https://api.baidu.com/v1/books/
		-https://api.baidu.com/v2/books/
    -4) 数据即是资源,均使用名词(可复数)***********
    	-接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
        -一般提倡用资源的复数形式,不要使用动词
        -查询所有图书
        	-https://api.baidu.com/books/
            -https://api.baidu.com/get_all_books/ # 错误示范
            -https://api.baidu.com/delete-user    # 错误的示范
            -https://api.baidu.com/user           # 删除用户的示例:疑问:到底是删还是查?
                
   -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     - 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&limit=3:指定返回记录的开始位置
        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)  响应状态码
		-返回数据中带状态码
		-{'code':100}
        
   -8) 返回结果中带错误信息
		-{'code':100,'msg':'因为xx原因失败'}

   -9) 返回结果,该符合以下规范
		GET /collection:              返回资源对象的列表(数组)
        GET /collection/resource:     返回单个资源对象(字典)
        POST /collection:             返回新生成的资源对象    (新增后的对象字典)
        PUT /collection/resource:     返回完整的资源对象 (修改后的对象字典)
        PATCH /collection/resource:   返回完整的资源对象 (修改后的对象字典)
        DELETE /collection/resource:  返回一个空文档   ()
        
   -10) 返回的数据中带链接地址
		-查询id为1的图书接口,返回结果示例
    	{'code':100,
         'msg':'成功',
         'result':
             {'title':'银瓶梅',
              'price':12.3,
              'publish':'https://127.0.0.1/api/v1/publish/3'
             }
        }

七 cbv源码回顾

#  cbv本质

# 1 请求来了,路由匹配成功执行 path('index/', views.Index.as_view()),
	执行views.Index.as_view()()
# 2 本质是执行as_view()内部有个闭包函数view()
# 3 本质是view()---》dispatch()
# 4 dispatch内部,根据请求的方法(get,post)---->执行视图类中的def get  def post
# drf:APIView的源码分析

    def as_view(cls, **initkwargs):
        # 这句话执行完成返回 view闭包函数的内存地址
        view = super().as_view(**initkwargs) # 调用父类(View)的as_view
        view.cls = cls
        view.initkwargs = initkwargs
        view=csrf_exempt(view)  # 局部禁用csrf
        return view

 # 装饰器的使用方式
    @csrf_exempt   ====>view=csrf_exempt(view)
    def view():
        pass

# 请求来了,会执行上面返回的view()---->self.dispatch(APIView的dispatch)

# APIView的dispatch方法
    def dispatch(self, request, *args, **kwargs):
		# 把原生的request,封装进新的Request对象(drf的Request)
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request 

        try:
        	# 重点(频率,认证,权限。。。)
            self.initial(request, *args, **kwargs)

            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
			# 这个request新的requst,是drf中Request对象
            # response是原生response
            response = handler(request, *args, **kwargs)

        except Exception as exc:
            # 全局异常
            response = self.handle_exception(exc)
		# 把原生response包装了一下
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response

八 drf基本使用及request源码分析

1 APIview源码分析

1) APIview的as_view
	-【请求来了,路由匹配成功执行,执行视图类,如Index的 as_view(),但是Index类没有 as_view() ,去父类APIView中找 as_view() 】
	-在APIView内部还是执行了View的闭包函数view
    -禁用掉了csrf
    -一切皆对象,函数也是对象  函数地址.name=lqz
    
2) 原生View类中的as_view中的闭包函数view
	-本质执行了self.dispatch(request, *args, **kwargs),【self是Index,所以又去父类找,执行的是APIView的dispatch】

3) APIView的dispatch	
    def dispatch(self, request, *args, **kwargs):
        # 此处request是DRF的Request类的对象,内部有request._request,是原生request,【drf作者进行了高级封装】
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request

        try:
            self.initial(request, *args, **kwargs)
            '''
            # self.initial,内部没有,于是找到了APIView的initial
            # 认证,权限,频率
            self.perform_authentication(request)
        	self.check_permissions(request)
        	self.check_throttles(request)		  --通过配置限制
            '''
			# 根据请求的方法(get,post)---->通过反射看请求是否是允许的请求---->是,执行视图类中的def get  def post
            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
			# 请求通过,执行handler,就是执行视图类中的def get  def post
            response = handler(request, *args, **kwargs)

        except Exception as exc:
            # 失败,全局的异常捕获
            response = self.handle_exception(exc)
		# 把视图函数(类)返回的response,又包装了一下
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response

2 Request类分析

1) Request类
	-request._request     : 原生request
    -request.data         : post请求提交的数据(urlencoded,json,formdata)
    -request.user         : 不是原生的user了
    -request.query_params : 原生的request.GET,查询参数,为了遵循restful规范
    -requset.FILES        : 新的
    -重写了__getattr__,新的request.原来所有的属性和方法,都能直接拿到
        def __getattr__(self, attr):
            return getattr(self._request, attr)
posted @ 2021-06-28 06:14  越关山  阅读(249)  评论(0)    收藏  举报