昨日回顾
1 web应用模式开放模式
2 API接口
3 接口测试工具
4 restful规范(重点)
5 djangorestframework:drf,django的app,快速的写出符合restful规范的API接口
6 drf的执行流程(APIView源码:request对象,认证,权限,频率,捕获全局异常,响应对象)
7 序列化器(序列化,反序列化,数据校验):(重点** ** ** )
- Serializer
- 字段自己写,字段类型,字段属性
- read_only write_only
- 序列化:实例化得到对象: instance, many, data (many= True : __call__)
- 对象. data:字典
- 反序列化
- 重写:create,update
- 返序列化的校验通过,修改会触发update,新增会触发create
- 反序列化的数据校验(三种方式):源码部分
- 扩展:source,SerializerMethodField
- ModelSerilalizer
- 内部类
- class Meta :
model = models. Book
fields = '__all__'
exclude= [ ]
read_only_field= [ ]
extra_kwargs= { }
depth= 1
- Serializer用法,重写字段,指定字段类型,字段参数
- 局部钩子,全局钩子
- 不需要重写create和update(经常看到重写)
8 请求和响应(次重点)
- Request
- request. data
- request. query_param
- 读源码:重写了__getattr__
- Response
- 客户端请求数据看到的样子(json,浏览器)
- 局部配置:在视图函数中renderer_classes = [ ]
- 全局配置:setting中配置
- drf默认有一套配置文件
9 视图(重点)
- 2 个视图基类:APIView和GenericAPIView
- GenericAPIView:
- queryset = None
- serializer_class = None
- get_queryset:获取要序列化的数据(可以重写,自己定制规则)
- get_serializer:获取序列化类(可以重写,自己定制返回哪个序列化类)
- get_object:返回单个对象,通过pk查的(可以重写,返回谁,单个对象就是谁)
- 5 个视图扩展类( rest_framework. mixins)
CreateModelMixin:create方法创建一条
DestroyModelMixin:destory方法删除一条
ListModelMixin:list 方法获取所有
RetrieveModelMixin:retrieve获取一条
UpdateModelMixin:update修改一条
- 9 个视图扩展类
CreateAPIView: 继承CreateModelMixin, GenericAPIView,有post方法,新增数据
DestroyAPIView:继承DestroyModelMixin, GenericAPIView,有delete方法,删除数据
ListAPIView:继承ListModelMixin, GenericAPIView, 有get方法获取所有
UpdateAPIView:继承UpdateModelMixin, GenericAPIView,有put和patch方法,修改数据
RetrieveAPIView:继承RetrieveModelMixin, GenericAPIView,有get方法,获取一条
ListCreateAPIView:继承ListModelMixin, CreateModelMixin, GenericAPIView,有get获取所有,post方法新增
RetrieveDestroyAPIView:继承RetrieveModelMixin, DestroyModelMixin, GenericAPIView,有get方法获取一条,delete方法删除
RetrieveUpdateAPIView:继承RetrieveModelMixin, UpdateModelMixin, GenericAPIView,有get获取一条,put,patch修改
RetrieveUpdateDestroyAPIView:继承RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView,有get获取一条,put,patch修改,delete删除
- 视图集
ViewSetMixin:重写了as_view (一旦继承了它,路由就变了)
ViewSet: 继承ViewSetMixin和APIView
GenericViewSet:继承ViewSetMixin, generics. GenericAPIView
ModelViewSet:继承mixins. CreateModelMixin, mixins. RetrieveModelMixin, mixins. UpdateModelMixin, mixins. DestroyModelMixin, mixins. ListModelMixin, GenericViewSet
ReadOnlyModelViewSet:继承mixins. RetrieveModelMixin, mixins. ListModelMixin, GenericViewSet
10 路由( 重点)
- 三种方式配置路由
- 自动生成路由
- 导入SimpleRouter,实例化得到对象
- router. register( 'book' , 视图类(必须继承ViewSetMixin及它的字类))
- 两种方式注册进路由中
- urlpatterns += router. urls
- urlpatterns = [
. . .
url( r'^' , include( router. urls) )
]
- 半自动
url( r'books/' , BookView. as_view( { 'get' : 'list' } ) )
- 原始的
- action装饰器(也会自动生成路由)
- 127.0 .0 .1 / books/ get_new_5 detail= False
- 127.0 .0 .1 / books/ pk/ get_new_5 detail= True
- @action( methods= [ 'put' ] , detail= True )
def get_new_5 ( self, request, pk) :
return Response( { 'msg' : '获取5条数据成功' } )
今日内容
1 drf认证功能介绍
0 认证- 频率- 权限
1 认证: 用户是否登录到系统中, 混合开发中可以操作浏览器的cookie的存取, 但分离开发中, 无法操作浏览器, 并且前端也并不一定是浏览器. 所以drf中要自己写认证.
2 JWT: 后期基本上用这个
3 自定制的认证
2 认证功能源码分析
1 :
- - - > APIView
- - - > dispatch
- - - > self. initial( request, * args, ** kwargs)
- - - > self. perform_authentication( request)
- - - > request. user( drf的request中的user)
- - - > self. _authenticate( self) ( Request类的方法)
- - - > 在Request对象实例化的时候传入的- - - > Request在什么时候实例化的?dispatch的时候- - - > APIView:self. get_authenticators( ) - - - > return [ auth( ) for auth in self. authentication_classes] - - - > 如果在自己定义的视图类中写了authentication_classes= [ 类1 ,类2 ] - - - > Request的self. authenticators就变成了我们配置的一个个类的对象
2 self. _authenticate( self) : Request类的方法
def _authenticate ( self) :
for authenticator in self. authenticators:
try :
user_auth_tuple = authenticator. authenticate( self)
except exceptions. APIException:
self. _not_authenticated( )
raise
if user_auth_tuple is not None :
self. _authenticator = authenticator
self. user, self. auth = user_auth_tuple
return
3 只要在视图类中配置authentication_classes = [ MyAuthen. LoginAuth, ]
就会执行上面的方法,执行认证
3 自定义认证类
1 使用
- 定义一个类,继承BaseAuthentication
class LoginAuth ( BaseAuthentication) :
def authenticate ( self, request) :
token = request. GET. get( 'token' )
res = models. UserToken. objects. filter ( token= token) . first( )
if res:
return 元组
else :
raise AuthenticationFailed( '您没有登录' )
- 重写authenticate方法
- 局部使用和全局使用
- 局部:在视图类中配置(只要配置了,就是登录以后才能访问,没配置,不用登录就能访问)
authentication_classes = [ MyAuthen. LoginAuth, ]
- 全局
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES" : [ "app01.MyAuthen.LoginAuth" , ]
}
- 注意:
1 认证类,认证通过可以返回一个元组,有两个值,第一个值会给,request. user, 第二个值会给request. auth
2 认证类可以配置多个,按照从前向后的顺序执行,如果前面有返回值,认证就不再继续往下走了
4 认证功能局部使用和全局使用
1 全局使用(所有接口,都需要登录才能访问)
- 在配置文件中
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES" : [ "app01.MyAuthen.LoginAuth" , ]
}
2 局部使用
- 在想局部使用的视图类上
authentication_classes = [ MyAuthen. LoginAuth, ]
3 局部禁用
- 在想禁用的视图类上
authentication_classes = [ ]
5 自定义权限功能(重点)
1 登录成功以后,超级用户可以干某些事,普通用户不能干- - - 》超级用户可以查看某些接口,普通用户不能查看
2 使用写一个类继承BasePermission,重写has_permission
class SuperPermission ( BasePermission) :
def has_permission ( self, request, view) :
if request. user. user_type == '1' :
return True
else :
return False
3 局部使用和全局使用
- 在想局部使用的视图类上
permission_classes = [ MyAuthen. SuperPermission]
- 全局使用
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES" : [ "app01.MyAuthen.SuperPermission" , ]
}
- 局部禁用
permission_classes = [ ]
6 权限功能局部使用和全局使用
1 使用方式
- 在想局部使用的视图类上
permission_classes = [ MyAuthen. SuperPermission]
- 全局使用
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES" : [ "app01.MyAuthen.SuperPermission" , ]
}
- 局部禁用
permission_classes = [ ]
7 内置的权限和认证类
from rest_framework. exceptions import AuthenticationFailed
from rest_framework. permissions import BasePermission
拓展
1 select_related的使用
articleList= models. Article. objects. select_related( "category" ) . all ( )
for article_obj in articleList:
print ( article_obj. category. title)
2 mysql的悲观锁和乐观锁
3 drf内部内置了一些认证类,分别干了什么事
作业
0 整理出认证和权限的使用,局部配置和全局配置
1 写一个图书的5个接口出版社的5个接口和登录接口
-用户必须登录才能访问图书的5个接口
-必须超级用户登录后才能访问出版社5个接口
2 阅读认证源码,整理出流程
2(拓展)阅读权限源码,整理出流程(错误信息的中文显示)