CBV 执行流程 |
路由配置:url(r'^test/',views.Test.as_view()), --> 根据路由匹配,一旦成功,会执行后面函数(request) --> 本质就是执行了as_view内部的view函数 --> 内部又调用了self.dispatch --> 根据请方式,执行不同的方法(必然get请求,就会执行视图类的get方法)
自己分装一个类 重写dispatch方法,在执行父类的dispatch之前,写一些逻辑,请求来了,就会执行这些逻辑
from django.views import View class APIView(View): def dispatch(self, request, *args, **kwargs): # 写控制条件 ret = super().dispatch(request,*args,**kwargs) return ret class Test(APIView): def get(self,request,*args,**kwargs): return HttpResponse('ok收到了了')
restful规范 |
面向资源架构 10条
1 API与用户的通信协议,总是使用HTTPs协议 这个协议比HTTP协议更安全一些
2 域名有区分 ① https://api.example.com @https://example.com/api/ 两种书写方式
3 版本 可以放在路径中 可以放在请求头中
https://api.example.com/v1/
4 路径,是网络上任何东西都是资源,均使用名词表示(重点)
https://api.example.com/imgs
5 通过method 区分是什么操作(重点)
get 表示获取
post 提交数据表示新增
delete表示删除
patch/put 表示修改
6 过滤,通过在url上传参的形式传递搜索条件 是查询所有 还是某一个分类或标签下的某一个资源
7 状态码
{'code' :100}
8 信息处理,错误处理应返回错误信息
{'code':101,'msg':'用户名或密码错误'}
{'code':100,'msg':'登录成功'}
9 返回结果,针对不同操作,服务器像用户返回的结果
get请求的获取所有资源 127.0.0.1/api/v1/books 获取所有图书 {'code':100,'msg':'success',data:[{},{},{}]}
get获取一个资源 127.0.0.1/api/v1/books/3 获取id为3的图书 {'code':100,'msg':'success',data:{'name':'小右'}}
新增数据,把新增的数据再返回
修改了数据,返回完整的资源对象
删除数据,返回一个空文档
10 返回结果中提供链接
基于原生django开发restful的接口 |
写获取图书接口 前端不用用queryset 用json转成字符串
JsonResponse 默认是传送字典类型 想要传送非字典类型需要设置safe=False 中文会被JsonResponse按照ascii编码
def lide(request): if request.method == 'GET': books = models.Book.objects.all() # 列表推导式 l = [{'name': book.name, 'publish': book.publish} for book in books] res = {'code': 100, 'msg': '查询成功', 'data': l} # 把它发回前端 return JsonResponse(res, safe=False, json_dumps_params={'ensure_ascii': False})
源码
drf:APIView的源码,Request的源码 |
安装: pip3 install djangorestframework 第二种是pycharm安装
使用: 第一步,在写视图,都写cbv
from rest_framework.views import APIView class Books(APIView): def get(self,request): ''' request是被封装后的request,原生的request在requeset._rquest 如果想要用用原生的request中的属性,还是原来的用法,因为Request重写了__getattr__方法 原生django只能处理urlencoded和formdata编码,如果是jason格式,原生django是不能处理的,需要自己从body中自行处理的 也就是前面说的 只有json才可以看body request.data 不管前端传输的编码格式是urlencoded,formdata或者json,都是从里面取值 request.data request.query_params 是原来django原生的GET中的数据 self.FILES 就是上传的文件 :param request: :return: ''' dic={'name':'lqz','age':30,'height':178,'wife':['liuyifei','dilireba','langlixiaobailong']} return JsonResponse(dic)
在settings文件中配置 INSTALLED_APPS=[...,'rest_framework']
源码分析:
继承了APIView之后
1所有的请求都没有csrf的认证了
忽略校验
2 在APIView中as_view本质上还是调用了父类的as_view(View的as_view)
3 as_view中调用dispath --> 这个dispatch是APIView的dispatch(先从自身查找没有找父类APIView的找到dispatch)
APIView的dispatch方法:
1 对原生request对象做了一层装(面向对象的封装),以后再用的request对象是新的request对象
原生request对象里面有个GET(以get形式提交的数据)都拆到environ内部 django把数据取出来转成了QueryDict的对象
看具体怎么封装的打印一下request._request的类型拿到类之后from impot点击进入
QueryDict对象 GET方法上面的装饰器可能是个缓存的装饰器 不然每次都实例化一个QueryDict对象浪费资源
session不是原生requeset对象的属性,在中间件中放进去的(django.contrib.sessions.middleware.SessionMiddleware)
2 在APIView中self.initial(request,*args,**kwargs),里面有频率控制,权限控制和认证相关
3 根据请求方法执行视图类中的相应方法
视图类中方法的request对象,已经变成了封装后的request
drf的Request类:
1 原生的request是self._request
2 data(post提交的数据,urlencoded,formdata编码方式的数据,json格式)
提交的data的类型并不是固定的,可能是QuerDict post提交的数据类型,也可能是字典
3 query_params 就是原生request的GET的数据
4 上传的文件是从FILES中取
5 (重点)其他的属性,直接request.属性名当属性不存在就会执行该该方法(因为Request重写了__getattr__方法)
postman的安装和使用 |
模拟向接口发送请求,测试接口 它不是浏览器不会有重定向加反斜杠再走一遍