from app01 import views url(r'book/',views.Book.as_view)
as_view
是一个类方法,其实是一个闭包函数(内层函数包含对外层做用域的使用)前端
请求来了之后,调用as_view
方法,调用函数中的view
方法,view
方法是调用了dispatch
方法django
@classonlymethod def as_view(cls, **initkwargs): def view(request, *args, **kwargs): self = cls(**initkwargs) if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs # 若是调用的类Book没有写dispatch方法,就会调用View中的dispatch方法 return self.dispatch(request, *args, **kwargs) view.view_class = cls view.view_initkwargs = initkwargs return view
view 方法是一个闭包函数,最终调用了 dispatch 方法
getattr(self, 'get'[,default]) # 获取对象的get属性的内存地址,若是没有get,返回默认值 setattr(self, 'get', 'get__all') # 至关于将get的内存地址设置为get__all 的内存地址 hasattr(self,'get') # 判断对象是否有get 属性
dispatch
方法至关因而根据不一样的请求方式,分发到对应的函数属性中编程
def dispatch(self, request, *args, **kwargs): # http_method_names --> ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] if request.method.lower() in self.http_method_names: # 这里的self.http_method_not_allowed 是默认值,若是没有改method,获取其地址 # 若是是get请求,那么handler就是get;如果post请求,handler至关于post handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs)
class Books(View): # 获取全部图书 def get(self, request): print(type(request)) response = {'status': 100, 'data': None} books = models.Book.objects.all() # 先构造出全部书籍的字典的列表 ll = [{'name': book.name, 'price': book.price} for book in books] # 返回数据是json格式数据 response['data'] = ll # safe = True 表示数据能够是列表 return JsonResponse(response, safe=False)
请求 --> 调用View中的as_view --> 调用as_view中的闭包view --> view中会实例化产生一个对象 --> 调用对象的dispatch --> 没有,去类中找dispatch --> 没有dispatch -->
去View中找,找到dispatch,执行 --> 分发到不一样的函数,执行并返回
resful规范的接口,用fbv和cbv均可以,自定义方法,CBV中重写,FBV中利用装饰器json
API与用户的通讯协议,老是使用 HTTPs协议 ------ https比http安全api
https://api.example.com ----- 尽可能将API部署在专用域名(会存在跨域问题) https://127.0.0.1/api/ ----- 简单,推荐使用
每一个接口都应有版本跨域
https://example/api/v2 ----- v2 版本
视网络上任何东西都是资源,均使用名词表示(可复数)数组
https://example/api/v1/zoos https://example/api/v1/animals https://example/api/v1/employees
经过在url上传参的形式传递搜索条件安全
https://example/api/v1/zoos?limit=10 https://example/api/v1/animals?offset=20 https://example/api/v1/employees?name=tom
请求回去,须要有状态码服务器
200 OK - [GET]:服务器成功返回用户请求的数据,该操做是幂等的(Idempotent)。 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务) 204 NO CONTENT - [DELETE]:用户删除数据成功。 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操做,该操做是幂等的。 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。 403 Forbidden - [*] 表示用户获得受权(与401错误相对),可是访问是被禁止的。 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操做,该操做是幂等的。 406 Not Acceptable - [GET]:用户请求的格式不可得(好比用户请求JSON格式,可是只有XML格式)。 410 Gone -[GET]:用户请求的资源被永久删除,且不会再获得的。 422 Unprocesable entity - [POST/PUT/PATCH] 当建立一个对象时,发生一个验证错误。 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将没法判断发出的请求是否成功。
应返回错误信息,error当作keyrestful
{status:100,error:'错误信息写上'}
针对不一样操做,服务器向用户返回的结果应该符合如下规范
GET /collection:返回资源对象的列表(数组) GET /collection/resource:返回单个资源对象 POST /collection:返回新生成的资源对象 PUT /collection/resource:返回完整的资源对象 PATCH /collection/resource:返回完整的资源对象 DELETE /collection/resource:返回一个空文档
Hypermedia API,RESTful API最好作到Hypermedia,即返回结果中提供连接,连向其余API 方法,使得用户不查文档,也知道下一步应该作什么
{ status:100 msg:成功 url:127.0.0.1/books/1 }
它是一个app,只是用来快速的构建restful规范的接口
必定要在settings中注册 INSTALLED_APPS=[rest_framework]
from rest_framework.views import APIView class Books(APIView): # 如今这个request对象,已经不是原来django中的request对象了,它是rest_framework.request下的Request def put(self, request, pk): # django.core.handlers.wsgi.WSGIRequest----原来的djagno中的request的类 # 如今的request已经成了:rest_framework.request.Request # 之后再取数据,直接从request.data中取 print(request.data) # 前端传过来的编码格式:json格式:{'name': '水都是', 'price': '15'} # 前端传过来的编码格式:urlencoded格式:<QueryDict: {'name': ['红楼梦'], 'price': ['15']}> # request.data是谁的对象? # request.data不一样编码格式过来,它多是不一样类的对象,可是用法是同样的 # 原来的request是:request._request print(type(request._request)) print(request._request.GET) # 也能取出来(method,GET,POST,BODY) print(request.GET) return JsonResponse({'status': 100, 'msg': '修改为功'})
request.data
是个方法,经过property装饰器包装成了属性,前台传过来body体中数据的数据,放在里面
request.query_params
这个是原来GET中的数据rest_framework.request.Request
的对象{% csrf_token %}
请求 --> rest_framework的as_view --> super调用父类View的as_view --> 父类中as_view调用比和函数view,实例化产生一个对象 --> 调用改对象的dispatch --> 自身没有,类中也没有,去父类中APIView中 --> 有dispatch方法 --> 调用rest_framework中的dispatch --> 分发到get、post、put等函数中执行