zoukankan      html  css  js  c++  java
  • drf5

    上节回顾

    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 用户是否登录到系统中
    2 后期基本上会用JWT的认证
    3 自定制的认证
    

    2 认证功能源码分析

    1 APIView---》dispatch---》self.initial(request, *args, **kwargs)--》self.perform_authentication(request)---》Request.user--->self._authenticate(self):Request类的方法---》self.authenticators: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: # BookView中配置的一个个类的对象
                try:
                    user_auth_tuple = authenticator.authenticate(self)  # 这个地方其实是两个参数,一个是类调用了绑定方法是自己的对象(对象调用自己的绑定方法可以不传),一个是传的request的对象,所以只写了request的对象
                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, ]
    	就会执行上面的方法,执行认证
        第一张图是在自建的py文件中写的认证规则,第二张图是视图类(第二张图中的update_or_create是表示更新表或者创建表后面的两个参数defaults=更新的内容,**kwargs接收的key=value的值,如果有内容,则使用defaults中的值更新,如果没有则将defaults和**kwargs的值一起写入表中)
    
    image-20201110163844429 image-20201110164213566

    3 自定义认证类(重点)

    1 使用
    	-在app的下新建一个py文件定义一个认证的类,继承BaseAuthentication,-重写authenticate方法
    	class LoginAuth(BaseAuthentication):
            def authenticate(self, request): # 此处必须要有request参数,否则无法取出数据校验
                token = request.GET.get('token')
                res = models.UserToken.objects.filter(token=token).first()
                if res:
                    return 元组   # 返回元组,会被解压赋值给(self.user,self.auth),就是将表中的对象和token返回,self是新的request的对象,因此视图函数中就能得到request.user当前登录的用户,request.auth就是token
                else:
                    raise AuthenticationFailed('您没有登录') 
        -局部使用和全局使用
            -局部:在视图类中配置(只要配置了,就是登录以后才能访问,没配置,不用登录就能访问)
                authentication_classes = [MyAuthen.LoginAuth, ]
            -全局
            REST_FRAMEWORK = {
            "DEFAULT_AUTHENTICATION_CLASSES": ["app01.MyAuthen.LoginAuth", ]
            }    # 全局使用包括登录,会死循环,所以会将登录出设置成局部禁用
       -注意:
    	1 认证类,认证通过可以返回一个元组,有两个值,第一个值会给,request.user,第二个值会个request.auth
        2 # 认证类可以配置多个,按照从前向后的顺序执行,如果前面某一个有返回值,认证类就不再继续往下走了,后面的认证类就不会执行。(因为源码里面用的for循环和return,如果走了return返回元组的地方,那么for循环就直接结束了)
    

    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):
            message='显示的内容'   # 权限功能不通过是显示的内容
            def has_permission(self, request, view):
                # Return `True` if permission is granted, `False` otherwise. 返回True,有权限,返回False,没有权限访问
                # 下面的是判断如果是超级用户可以访问,除了超级用户以外,都不能访问
                if request.user.user_type == '1':   # 其中user_type是自己在表中设置的字段名
                    return True
                else:
                    return False
                
    3 局部使用和全局使用
    	-在想局部使用的视图类上加上
    	permission_classes = [MyAuthen.SuperPermission]
        -全局使用
          REST_FRAMEWORK = {
            "DEFAULT_PERMISSION_CLASSES": ["app01.MyAuthen.SuperPermission", ]
            }    # 配置中是自己写的认证类
         -局部禁用
        permission_classes = []
    

    image-20201110184158652

    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:
            #  Doesn't hit the database, because article_obj.category
            #  has been prepopulated in the previous query.
            #不再查询数据库,因为第一次查询,数据已经填充进去了
            print(article_obj.category.title)
    
  • 相关阅读:
    Zjnu Stadium(hdu3047带权并查集)
    cocos2d-x结合cocosbuilder,不同屏幕适配小结
    分布式爬虫系统设计、实现与实战:爬取京东、苏宁易购全网手机商品数据+MySQL、HBase存储
    Generating RSA keys in PKCS#1 format in Java--转
    nodejs安装node-rsa遇到的问题及解决
    spring-redis-data的一个坑
    node-rsa加密,java解密调试
    MySQL 四种事务隔离级别详解及对比--转
    从实际案例聊聊Java应用的GC优化--转
    动态可缓存的内容管理系统(CMS)
  • 原文地址:https://www.cnblogs.com/feiguoguobokeyuan/p/14012526.html
Copyright © 2011-2022 走看看