b站drf笔记


drf:django rest framework框架

luffy:讲的一般
三种api接口规范:
restful  资源状态转换  规范(建议)
rpc 远程过程调用 
soap  用于智能家居

内容回顾:

  • 1、开发模式
    • 普通开发方式(前后端放在一起写)
    • 前后端分离 vue route-bind ajax请求展示 前端伪造数据测试 通过func获取 双向绑定
  • 2、后端开发
    • 为前端提供URL(API/接口开发)
    • 注: 永远返回HttpResponse
      • 3、django FBV、CBV
  • FBV function base view 视图是函数
  • CBV class base view 视图是类

01

FBV request.method == "GET":

02

CBV 用类.方法 执行 postman提交POST请求 自动执行class中的post、get、put、delete方法

03 04

4列表生成式
class Foo:
pass
class Bar:
pass

v = []
for i in [Foo,Bar]:
obj = i()
v.append(obj)
v = [item() for item in [Foo,Bar]]
v 对象列表
5面向对象
- 继承
- 多态
- 封装 
- 对同一类方法进行封装   
class File: 文件增删改查方法  
def __init__(self,a1,a2):
self.a1 = a1
self.xx = a2
def get(self):
pass
def add(self):
pass
obj1 = File(123,666)
obj2 = File(456,999)

class DB: 数据的方法

  • 将数据封装到对象中
from django.shortcuts import render

# Create your views here.


class Resquest(object):

    def __init__(self,obj):
        self.obj = obj

    @property
    def user(self):
        return self.obj.authticate()

class Auth(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def authticate(self):
        return self.name

class APIView(object):
    def dispatch(self):
        self.f2()

    def f2(self):
        a = Auth('alex',18)
        b = Auth('oldboy',11)
        req = Resquest(b)
        print(req.user)

obj = APIView()
obj.dispatch()
内容详细:
0、FBV、CBV
CBV, 基于反射实现根据请求方式不同,执行不同的方法
原理:
a. 路由
url -》 view方法 -》 dispatch 方法(反射执行其他,GET/POST/PUT/DELET)

05

多个类要使用相同dispatch方法 继承 避免重复编写

面试题 CSRF 基于django中间件实现 1、django中间件 最多5个方法

  • process_request 先执行
  • process_view 在执行 CSRF token
  • process_response
  • process_exception 报错执行
  • process_render_template 返回对象render方法 就执行

06

2、使用中间件做过什么?

  • 权限
  • 用户登录验证
  • django CSRF是如何实现的? process_view方法
    • 检查视图是否被 @csrf_exempt (免除CSRF认证)
  • 去请求体或cookie中获取token
  1. 中间件中csrf全局使用 @csrf_protect 单视图使用

07

2种设置方法

  • 全局
  • 单视图
  • 小知识
方法一
csrf时需要使用
- @method_decorator(csrf_exempt)
- dispatch
在CBV中 配置方法
class StudentsView(MyBaseView, View):
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(StudentsView, self).dispatch(request, *args, **kwargs)

方法二
@method_decorator(csrf_exempt, name='dispatch')
class StudentsView(MyBaseView, View):
    pass

总结:

CBV 基于用户请求方法反射实现i
流程 url -》 views -》 dispatch -》 反射 执行内部方法
取消csrf认证(装饰器要加到dispatch方法上且method_decorator装饰)
  • 扩展:
  • csrf
  • 基于中间件的process_view方法
  • 装饰器给单独函数设置认证 或者 取消认证

  • API文档 ```python 用户管理: 返回值 { code: 666, 'status':false, 'message':[], }

vue $.ajax({

})

```python
restful 规范(建议)CRUD 
1.根据method不同做不同的操作,例如:
基于FBV实现
urlpatterns = [
    url(r'^users/', views.user),
    url(r'^students/', views.StudentsView.as_view()),
    url(r'^get_order/', views.get_order),
    url(r'^add_order/', views.add_order),
    url(r'^update_order/', views.update_order),
    url(r'^del_order/', views.del_order),
    url(r'^order/', views.order),

    ]

def order(request):

    if request.method == 'GET':
        return HttpResponse('获取订单')
    elif request.method == 'POST':
        return HttpResponse('创建订单')
    elif request.method == 'PUT':
        return HttpResponse('更定订单')
    elif request.method == "DELETE":
        return HttpResponse('删除订单')

基于CBV实现

urlpatterns = [
    url(r'^users/', views.user),
    url(r'^students/', views.StudentsView.as_view()),
    url(r'^get_order/', views.get_order),
    url(r'^add_order/', views.add_order),
    url(r'^update_order/', views.update_order),
    url(r'^del_order/', views.del_order),
    url(r'^order/', views.OrderView.as_view()),

    ]

class OrderView(View):
    def get(self,request,*args,**kwargs):
        return HttpResponse('获取订单')

    def post(self, request, *args, **kwargs):
        return HttpResponse('创建订单')

    def put(self, request, *args, **kwargs):
        return HttpResponse('更新订单')

    def delete(self, request, *args, **kwargs):
        return HttpResponse('删除订单')

参考: https://www.cnblogs.com/wupeiqi/articles/7805382.html

PI与用户的通信协议总是使用HTTPs协议
域名 
https://api.example.com                         尽量将API部署在专用域名会存在跨域问题
https://example.org/api/                        API很简单
版本
URLhttps://api.example.com/v1/
请求头                                                  跨域时引发发送多次请求

注意跨域 要解决跨域问题 域名不同 www.myjishu.com/api/v1

推荐使用https
子域名 or 二级域名
版本
面向资源编程 -- 尽量使用名词  比如order  而不是get_order
PUT      :在服务器更新资源(客户端提供改变后的完整资源)  局部更新
PATCH  :在服务器更新资源(客户端提供改变的属性)     全部更新

筛选条件 https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数

状态码
2xx 
4xx  client端问题
5xx  server端

状态码 + code结合  status浏览器显示的状态码
class OrderView(View):
    def get(self,request,*args,**kwargs):

        ret = {
            'code':10000,
            'msg': 'xxx',
        }

        return HttpResponse(json.dumps(ret),status=201)
处理 error
返回结果
GET /collection返回资源对象的列表数组
GET /collection/resource返回单个资源对象
POST /collection返回新生成的资源对象
PUT /collection/resource返回完整的资源对象
PATCH /collection/resource返回完整的资源对象
DELETE /collection/resource返回一个空文档

/order/
[
{'id',1,
'name':'苹果',
url: http://www.myjishu.com/1/
},
{'id',2,
'name':'橘子'}
]

否则就需要
/order/1/ 来访问
这些就是restful定义的规范可以不遵循
谈谈自己对restful api 规范的认识
会restful之前
定义一些规范 更好的处理 url体现出对api的操作
没用之前....用了之后....
多url 增删改查 == 合并成一个url单url代表CRUD 
版本状态码2xx/4xx/5xx)、methodCRUD
cors 跨域问题  跨源资源共享  jsonp  
协同开发统一更加规范
10个规则

不引用drf 也可以通过django实现 restful规范只是比较麻烦要自己去实现对应的restful规则
  • 注意 推荐使用CBV
2django rest framework 框架
 pip3 install djangorestframework

class APIView(View):
pass

class OrderView(APIView):
pass

继承APIView获取的功能越多之前类的继承注意继承的顺序从左到右 ==  

a. cbv 执行dispatch 

http://127.0.0.1:8000/app01/dog/?token=123

a. 用户认证
仅使用
源码流程
self.dispatch

复习:

生成器迭代器装饰器反射
中间件
csrf token
CBV本质 dispatch 反射实现  
restful规范 
- 10条规范  
- 认识
Djangorestframework框架
- 如何验证基于数据库实现用户认证
- 源码流程 (面向对象回顾流程) 继承 封装 
- 列表生成式
- 类的封装继承

09

用户验证  基于数据库实现

@csrf_exempt
def user(request):
    # getattr(obj.request.method)
    user_list = ['alex', 'oldboy']
    return HttpResponse(json.dumps((user_list)))


class MyBaseView(object):
    def dispatch(self, request, *args, **kwargs):
        print('before')
        if request.method == 'GET':
            print('after')
        ret = super(StudentsView, self).dispatch(request, *args, **kwargs)
        return ret

内容回顾:

1 中间件  
2csrf原理  views 判断是否通过csrf   全局局部   返回一个随机字符串  验证 匹配就通过  
3rest 10个规范   api版本httpsstatus码method错误码url传参返回结果加域名前面 跨域jsonp),带参数URL  
4面向对象  属性方法封装到类   继承    多态 本身就是多态

封装
1将构造方法封装到类中
2将重复方法提取到一个类中

继承
共同的属性和方法 提取到基类中实现
多继承 从左到右  经典类 新式类   广度优先深度优先
从根部开始找谁实例化对象就从谁开始找
多态 本身就是多态
点出方法就支持这个功能

5django请求生命周期 包含rest framework框架
uwsgi -中间件 - url - views 视图 FBVCBVdispatch反射找到对应函数 - templates / models  
- view rest framework 重写dispatch  实现 
csrf token  装饰器添加方式 CBV

今日内容

  • 1、认证
  • 2、权限
  • 3、节流(访问频率控制)
  • 4、版本
判断是否登录?前后端分离  
rest framework  
cors 跨域 
关于token  其实就是类似session的东西,只是自己实现了保存,session基于中间件实现的  
token在请求头、请求体都一样,只是显示的位置不同,放url上也可以,在cookie中也行,整个流程就是client浏览器 cookie -》前端 -》 后端接收  
三方操作,前端传递给后端token是通过url来做,比较简单避免跨域问题,如果放请求头:
复杂请求头,需要发两次,先预检在请求 
放在url 最简单,也可以放cookie,
django的请求周期  
中间件、view中都可以实现认证   只是 drf 帮忙实现这个功能  通过url传递token到后端认证
  • 1、认证 ```python a.问题:有些API需要用户登录成功之后,才能访问,有些无需登录就能访问 == rbac白名单实现 b.基本使用认证组件
    存在就创建不存在就更新 update_or_create() 想起来有个简单的判断方式 存在 or 不存在,取代if判断,if not xx 缩进取代if判断 解决: a. 创建两张表 b. 用户登录(返回token并保存到数据库) 需要登录的页面 必须通过认证才能查看

通过Python格式化Json数据,-m json.tools

c. 认证流程原理

  • self开始找 class Authtication(object): pass 自定义认证类 三种返回值 一般不加多个认证类 空 匿名
    抛出异常 认证失败
    元祖 user auth ``` 10

  • d. 再看一遍源码

    1认证配置 settings 局部视图使用 & 全局视图
    2全局使用的认证类    匿名时request.user = None
    

11

  • e. 内置的认证类
1认证类必须继承 from rest_framework.authentication import BaseAuthentication
2其他认证类BasicAuthentication 认证  通过用户名和密码认证 

一般自定义实现通过token来实现认证

这里中间件想到了什么
对了就是思考这个全局的配置认证登录是不是通过中间件实现的
不是基于中间件就是通过url进来之后访问到视图CBV在通过APIView类 -认证 self.dispatch 来实现的   
drf自带的基本的认证
梳理
认证 一个类 
1使用
    - 创建类 继承 BaseAuthentication  实现 authenticate
- 返回值
- None  我不管了下一个认证来执行
- exceptions.AuthenticationFailed('用户认证失败')
- 元素1元素2 # 元素1赋值给request.user , 元素2 赋值给 request.auth
- 局部使用

12

2源码流程
- dispatch  
- 封装request
- 获取定义的认证类(全局/局部)通过列表生成式创建对象
- initial
- perform_authentication
    request.user(内部循环...)
问题:
django 中post方法传值,用普通的request.POST.get(‘value’) 是没法正常接收到前端传递过来的值的
这里需要用其他的方法获取
1.request.data  接收到的是一个dict 直接用[]取对应的值即可,这是明文的
2.request.body 接收到的是一个二进制的文本流,需要自己转码,也是能够接收到值的
3.request._request.POST.get  这种方法只能接收到get方式发送的值,post是接收不到的
所以,当你前端用post方式传递值后端接收到时None时,可以尝试更改接收方式,用data或者body都是可以接收的
回顾那些数据在body里面
记起来了ajax提交的时候会提交的数据这里可以用request.POST.get() 获取  
$.ajax({
url:url,
method: 'post',
data: {
username: 'ceshi',
password: '123',
},
success:function(res){

}
})

这种方式会提交到request.body中获取的就是字符串必须手动json.loads() 再用对象处理  如果返回直接json.dumps() 返回获取也是字符串js中需要用JSON.stringify() 进行转对象处理 
$.ajax({
    type: "POST",
    url: "/Service/ListString",
    contentType: "application/json",
    dataType: "json",
    data: JSON.stringify({
        "BuIds": ["1", "2", "3"]
    }),
    success: function(jsonResult) {
        alert(jsonResult);
    }
});

一般用法,直接默认格式传递,后端直接request.POST.get()获取,返回也JsonResponse也通过json对象返回,也减少一次转换,否则就需要手动在服务端body json.loads(),前端 JSON,stringify() 转换为对象,比较麻烦

先看后面在练习 通过认证 request中赋值 必须登录,没有token就报错

  • 2、权限
问题不同视图用不同的权限来访问
基本使用  跟认证类似  
源码流程

梳理
1基本使用
-   继承 BasePermission  必须 实现 has_permission方法
- 返回值
True有权访问
FALSE: 无权访问 
- 局部

-全局  settings
2源码流程

自己写视图 or 中间件都可以实现只是用restful framework组价就在他的里面实现

限制访问频率 节流 控制访问频率 
访问记录 = {
身份证号: [12:10:10,12:10:9,12:10:8,12:10:7,12:10:6,12:10:5]
}

访问记录 = {
用户IP: [....]
}
匿名用户 -- 换ip  没招
注册用户 --绑定人  
注册10w用户 ---  绑定手机号唯一标识

所有都是通过ip限制 也可以基于用户名

13

内置控制类

梳理
匿名 ip会换
登录用户  注册大量账号  绑定手机号  限制
a. 基础使用
- 继承BaseThrottle  实现 alow_request wait 方法
- 继承SimpleRateThrottle 实现 get_cache_key scope = luffy 配置文件中的key

b. 局部
# throttle_classes = [VisitThrottle, ]
c全局
settings

记返回值 or 源码认证权限节流
work 
1、中间件
2、csrf原理
3、rest 10规范  认识
4、面向对象
5、djangorestframework 
- 如何验证(基于数据库实现用户认证)
- 源码流程(面向对象回顾流程)dispatch  
django请求声明周期 包含rest framework框架    
PS:dispatch
6、rest framework 认证流程(封装Request)
7、rest framework 权限流程 
8、rest framework 节流流程
  • 代码:
认证Demo
权限Demo   用户类型不同,权限不用
节流Demo   匿名  登录用户  全局/局部视图中使用 
三组件组合
内容概要
1版本  *
2解析器   contenttype = application/x-www-form-urlencoded *
3序列化  ****
- 请求数据进行校验
- Queryset进行序列化
4分页  **
5路由  自动路由 **
6视图 CBV  APIView   FBV @APIView   **
7渲染器 *

认证权限节流
10个规范
10个组件
内容回顾
谈谈面向对象 
封装 相同属性和方法封装到一个类  构造方法状态到一个类中     自定义分页  restful 源码  request封装 新request 
继承  基类派生类  公共实现    多继承  经典类 新式类  APiView -VIew   form表单 -form - modelform
多态 鸭子模型  鸭子呱呱叫 就是 鸭子  函数.方法   

class WX:
def send():
pass
class email:
def send():
pass
class Msg():
pass

def func(arg):
arg.send()

obj = Email()
func(obj)
arg多种形态不管是wx还是email传什么对象执行对应的send方法鸭子只要能send都能允许
django生命周期  
uwsgiref wsgi协议 django约束 -中间件 -url - views视图FBV  - templates /models
wsgi
wsgi 是协议 == 参数  
wsgiref是实现了wsgi协议的一个模块模块本质一个socket服务端性能太低
werkzeug  是实现了wsgi协议的一个模块模块本质一个socket服务端 flask框架
tornado  是实现了wsgi协议的一个模块模块本质一个socket服务端  自己写的socket 实现wsgi协议
uwsgi是实现了wsgi协议的一个模块模块本质一个socket服务端
基于wsgi实现

14

django生命周期 rest framework

中间件 -url -视图 CBV dispatch as_view() -> view() -> dispatch  -> 请求封装Request封装 -认证 -> 权限 -节流 -  反射执行method func执行 -返回经过中间件
注意 不是用中间件实现的全局配置是通过配置文件实现的只要走了dispatch 就会找setting中的配置有就会全局应用 or 视图局部应用
csrf token 这里在全局设置中间件 局部视图CBV排除方式不同
4、中间件 & 装饰器
登录在函数上面加装饰器 -- 视图局部
所有统一操作 -- 中间件  RBAC 权限控制  
csrf token原理  先来访问给随机字符串 带着再来验证  检测 获取  中间件 process_view 
session  原理  登录成功 返回随机字符串,通过随机字符串 db 获取所有值  Request.session  session中间件 process_request  process_response 写入到db
适用于所有请求批量做操作
场景:
- 基于角色的权限控制
- 用户认证
- csrf (说原理)
- session (说原理)
- 黑名单 通过ip process_request 
- 日志记录




5、rest框架原理
a. 认证流程
authentic 返回值  None   异常 (Request.user,request.auth)
b. 权限
has_permission
c. 节流
alow_request、wait
匿名 唯一标识 当做key放入 缓存  每个key弄个列表存放访问时间 每次访问把最后一个剔除掉 判断访问时间内请求的次数  
- ip 
- 代理ip
实名用户 
- 用户
详细
1版本
a.URL中通过get传参
自定义
http://127.0.0.1:8000/api/user/?version=v2


b. 在URL中传参(推荐使用)
版本在认证权限节流之前

总结
使用
配置文件
路由系统
视图
2解析器
Request.POST     
request.body   请求体 -转换 dict 
请求头 contenttype
前戏 django  request.POST / request.body 
1请求头要求
Content-Type:application/x-www-form-urlencoded'   # 默认类型  会传递到request.POST中 
PS: 如果请求头中的 Content-Type:application/x-www-form-urlencoded'  request.POST中才有值 去Request.body中解析数据
2数据格式要求
name=alex&age=18&gender=


a. form表单提交
<form method.....>
input...
</form>

b.ajax提交
$.ajax({
url:...
type:POST,
data:{name=alex,age=18}  # 内部转化 name=alex&age=18&gender=男
})

情况一
$.ajax({
url:...
type:POST,
headers:{Content-Type:application/json'}
data:{name=alex,age=18}   # 内部转化 name=alex&age=18&gender=男   ajax提交会用 
})
# body有值,POST无  因为头部类型不对   无法转换为字典格式  只能变成 "name=alex&age=18&gender=男" 字符串

情况二
$.ajax({
url:...
type:POST,
headers:{Content-Type:application/json'}
data:JSON.stringfy({name=alex,age=18})     # {name:alex,age:18}   JSON.parse()  前端需要格式化为JSON数据在传递

})
# body有值,POST无   头类型不对,格式也不对
json.loads(request.body) # 转化字典
在drf中解析器 request.data 直接获取解析后的字典

这里纠结的一点,其实序列化已经给请求格式做了限制,如果是上面&的方式,rest JOSN解析器肯定无法解析,校验都通过不了,也就不会存在这种问题,如果不用rest 解析器,django自带的request.body loads也可以转换json 的格式的数据,上面的方式传递根本不是json数据,header里面标识的确实json,只是通过request.body去获取,而且不能直接转换成对象处理,rest处理不了,这就是前端传递的数据格式的问题,要转换为json的数据

PS: 实际测试json格式的如果数据类型不行jsonrestful解析器会报错要能够解析前端传过来必须是格式化的json数据没有name=123&b=2 这种格式的无法解析 
    "detail": "JSON parse error - Expecting property name enclosed in double quotes: line 1 column 2 (char 1)"
rest_framework  解析器对请求体数据进行解析
总结使用配置
全局配置
使用 request.data

源码流程 & 本质
a.本质
请求头  主要包含 urlmethod状态码cookierefre 防盗链contenttypepostaccept 期望的返回格式User-Agent
请求方法
状态码 
b.源码流程
dispatch() request封装  解析器封装 
- request.data   parse  解析器解析   
ajax 这里也需要格式化 JSON.stringfy() 才能获取到request.data在常规中json.loads(request.body) 得到json的字典  
注意要传递json格式 就要预先格式化否则就是字符串 a=2&b=1 在request.body中不能作为字典对象使用
上传文件 参考https://www.cnblogs.com/wupeiqi/articles/7805382.html
3序列化
- 请求数据认证
- query_set序列化
类似写form 直接格式化  
choice 显示里面的值  stark已实现 model 有个对应方法 get_userinfo_display() 获取到choice的值

queryset 序列化 转换 json 返回 部分总结: 1、写类 继承2种 2、字段

a. gp = serializers.CharField(source='group.title')  # 外键  
b.自定义显示
rls = serializers.SerializerMethodField()  # 自定义显示
class Meta:
    model = models.UserInfo
    # fields = "__all__"
    fields = ['id','username','password','ooo','rls']
    # extra_kwargs = {'group':{'source':'group'},}

def get_rls(self, row):
    role_obj_list = row.role.all()
    ret = []
    for item in role_obj_list:
        ret.append({'id': item.id, 'title': item.title})
    return ret

3、自定义类

回顾:
版本
解析器  request.data
序列化  queryset 与model交互 返回model数据   用户请求数据
返回数据序列化
请求数据校验

3、自动序列化连表

4、生成连接  
- 前端拼接生成
- 反向解析生成 一般返回值或者id  url有时也会用
源码流程 
 对象 Serializer类处理
Queryset,ListSerializer 类处理
请求数据校验

问:自定义验证规则时,需要钩子函数?请问钩子函数如何写?

源码流程
1、今日内容
2、序列化自定义钩子函数

几个重点源码流程可以着重看下,比如认证、权限、节流 版本、解释器、序列化

django contenttype

今日内容概要
0. 序列化源码  搞清楚怎么查找的永远从self 对象开始找就不会错从头开始 源码可以多过几遍  
1分页
a. 分页看第n页每页显示n条数据  page max  size  一页显示多少条数据 
b. 分页在n个位置向后查看n条数据  limit  offset
c. 加密分页只能看到上一页和下一页一千万页也不会慢  记录 id最大值 id最小值  只扫10条  
一千万数据 分页  越到后面越慢  索引只能优化  不能解决 

总结
设计表结构  insert 数据  连表查询 group by  基础
数据量比较大  分页如何做
- 数据库性能相关索引优化  最近看过....   话题转换到rest formwork 分页 跟这个有关系  原生sql数据量大后变慢可以通过记住最大值最小值id解决但是url上直接输入99999会有问题发现fromwork源码里面url页码进行了加密做的挺好的
- 话题转移后开始介绍  10个组件10个规范  源码流程  请求封装  版本 .... django请求生命周期 

2视图  继承关系 
继承 APIVIew 继承 django View  
继承6个类 CRUD 局部更新 继承其他类 -> 2 -> 1

a.过去

b.现在

c.无用

d. GenericViewSet

总结
单条多条  GenericViewSet
a. 增删改查 ModelViewSet
b. 增删 CreateModelMixin DestroyModelMixin   GenericViewSet
c. 复杂逻辑 GenericViewSet  APIView

PS还债

3路由  as_view()   自动分发  
一个API 4个URL  至少2个URL 
官网 20行代码实现

会根据url进行分发全部在get中好一些减少一些判断比如查询多条单条需要做判断   直接在url区分  到不同视图  

4渲染器  友好的显示  序列化返回数据

5django组件contenttype
内容回顾
1rest规范 url https 版本 资源名词 过滤条件  请求头 method  域名 状态码返回 结果集 headlemidderware  10个规范
2rest framework 框架 其他语言也有  10个组件  前4个  CBV - view - dispatch -request请求封装 -认证  parse - 解析器 
initialize_request  initial返回视图  版本 认证 权限 节流  
版本控制  get传参  请求头  namespace  url上 一般放在url上  视图都相同  在全局配置上
认证 方法 返回值 出错  元祖 None
权限判断  True FALSE
节流 True  False  匿名用户 代理ip/ip来做 登录用户用用户来做
反射执行视图函数  解析器 请求头contenttype不同获取值不同  
request.body  json/application  
request.POST  有值  没有值 看request.body
解析器 可以解析多种格式数据
序列化     数据校验   Queryset序列化返回给用户
2 Serializer  modelSerializer  
字段三类CharField IntegerField  MyCharField 自定义 HyperlinkedIdentityField
 url 小bug   group = serializers.HyperlinkedIdentityField(view_name='gp', lookup_field='group_id', lookup_url_kwarg='xxx')
使用 应用Serializer 先实例化Serializer  传入instance    ser.data 获取数据 
ser = UserInfoSerializer(instance=users, many=True)
ret = json.dumps(ser.data, ensure_ascii=False)
请求校验
ser = UserGroupSerializer(data=request.data)
if ser.is_valid():
    print(ser.validated_data['title'])
else:
    print(ser.errors)

- 前4个组件源码流程  
- 序列化
url 版本 解析器 都是一次性配置
work
1序列化 == 源码  get_query() / 
2视图继承流程  page组件里面的序列化流程  
3写代码 
- jQuery 发送ajax请求
a.Vue
- 看到登录页面
- 数据用户名和密码发送ajax请求
- 用户列表页面  双向绑定展示  将用户数据显示在页面中
- 学生详细信息 
b.django rest framework 
- /auth/
返回token 
- /students/ 认证
返回学生列表
- /students/\d+/
返回学生详细信息
c.节流  
控制
- 匿名用户 2分钟访问10次
- 正常用户 2分钟访问20次
权限
PSCORS  端口不同跨域解决设置响应头 不用jsonp

luffy drf里面基本也是上面这些内容,只是在后面有点补充,加上讲的方式不对,不再看了,补充没有讲到的,笔记整理 (下午) 练习代码

10大组件 认证、权限、限流、序列化、解析器、视图、路由、渲染、分页、版本

10个规范 版本、域名、https、路径、method、过滤、状态码 status=1000、错误处理、返回结果、返回提供http地址

路由系统 CBV

http://127.0.0.1:8000/api/user/?version=v2

疑问: 新式类 VS 经典类

serializers.HyperlinkedIdentityField(view_name='gp',lookup_field='group_id',lookup_url_kwarg='xxx') url源码分析 找到是函数就加括号执行,不是函数就不加括号 源码分析

感悟: 练习可以多来几遍,视频也可以在过一遍,针对性的看,只看源码流程分析过程,正常倍速 目前练习一次,明天再来一次,源码过一遍,再来一次,三遍差不多

练习最后一节的分页这里,不急理清楚,快不能解决问题