• django_rest framework 接口开发(一)


    1 restful 规范(建议)
        基于FbV
            def order(request):
                if request.method=="GET":
                    return HttpResponse('得到订单')
                if request.method=="POST":
                    return HttpResponse('提交订单')
                if request.method=="PUT":
                    return HttpResponse('更改订单')
                if request.method=="DELETE":
                    return HttpResponse('删除订单')
        基于CBV()
            class order(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 如果用子域名方式(需要解决跨域问题)
        版本
        过滤
        
        a.cbv,
        继承APIVIew
        会执行dispatch()
            1,在里面的代码段
                [        request = self.initialize_request(request, *args, **kwargs)]#这句代码对原生requesst进行加工(丰富了一些功能)
    #  1 initialize_request里面有值 
                #  2 authenticators=self.get_authenticators(),  获取实例
                #  3 return [auth() for auth in self.authentication_classes]  #返回self.authentication_classes 对象实体类
                ## 获取原生 request 为 request._request
                ## 获取认证类的对象 request.authenticators 
                
                
                
                
            def _authenticate(self):#(源码解析)
            
            # 循环认证类的所有对象
            for authenticator in self.authenticators:
                try:
                    #  执行认证类authenticate方法
                    # 1 如果authenticate方法抛出异常,self._not_authenticated()执行
                    # 2 有返回值,必须是元组:(request.user,request.auth)
                    # 3 返回None,不管,下一个认证来处理
                    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
    
            self._not_authenticated() # 如果都没有,就异常
            
            
            
            内置认证类
                1 认证类,必须继承BaseAuthentication
                    返回值:
                        1 None:下一认证来执行,
                            没有就报异常
                        2 异常:没有通过认证
                        3 (元素1,元素2) # 元素1赋值给request.user;元素2赋值给request.auth
                2 其他认证类:BasicAuthentication
                3  使用:
                    1 局部使用:
                        配置authentication_classes=[x,]
                    2 全局使用:
                        配置文件
            内置权限类
                1 权限类,必须继承BasePermission
                    返回值:
                        1 True:有权访问
                        2 False:无权访问
                2  使用:
                    1 局部使用:
                        配置permission_classes=[x,]
                    2 全局使用:
                        配置文件
    
        
        梳理:
            认证,权限,频率
    版本:
        通过url_get传参(推荐URL传参)
            需要控制
                1 传递版本参数
                2 默认版本
                3 允许版本
    解析器
        本质:
            请求头,
            状态码
            请求方法
        parser_classes = [,]
        1 请求头要求 
            Content-Type:xxx/xxx
        2 数据格式要求
            name=xx&age=xx
            1 form 表单提交 
                自带请求头
                # 内部自动转化  name=xx&age=xx
                
            2 ajax 提交 
                情况一:
                    $.ajax({
                        url:...,
                        type:POST,
                        headers:{'Content-Type':'application/json'},
                        data:{name:xxx,age:xxx}
                    })
                    # 内部自动转化 name=xx&age=xx
                    # body有值, POST无
                情况二:
                    $.ajax({
                        url:...,
                        type:POST,
                        headers:{'Content-Type':'application/json'},
                        data:JSON.stringfy({name:xxx,age:xxx})
                    })
                    # 内部自动转化 name=xx&age=xx
                    # body有值, POST无
        3 rest_framework 解析器,对请求体数据进行解析 
             1 获取用户请求
             2 获取用户请求体
             3 根据用户请求体,交给parser_chlaaes去处理
             
             "DEFAULT_PARSER_CLASSES":['rest_framework.parsers.JSONParser','rest_framework.parsers.FormParser']
    序列化:
        
            1. 写类
                class RolesSerializer(serializers.Serializer):
                    id = serializers.IntegerField()
                    title = serializers.CharField()
        
                class UserInfoSerializer(serializers.ModelSerializer):
                    class Meta:
                        model = models.UserInfo
                        # fields = "__all__"
                        fields = ['id','username','password',]
        
            2. 字段 
                a. title = serializers.CharField(source="xxx.xxx.xx.xx")
                b. title = serializers.SerializerMethodField()
                   class UserInfoSerializer(serializers.ModelSerializer):
                        rls = serializers.SerializerMethodField()  # 自定义显示
    
                        class Meta:
                            model = models.UserInfo
                            fields = ['id','username','password','rls',]
                        
                        # 自定义方法
                        def get_rls(self, row):
                            role_obj_list = row.roles.all()
    
                            ret = []
                            for item in role_obj_list:
                                ret.append({'id':item.id,'title':item.title})
                            return ret
                c. 自定义类
                    
            3. 自动序列化连表
                class UserInfoSerializer(serializers.ModelSerializer):
                class Meta:
                    model = models.UserInfo
                    # fields = "__all__"
                    fields = ['id','username','password','group','roles']
                    depth = 1 # 0 ~ 10
        
            4. 生成链接
                class UserInfoSerializer(serializers.ModelSerializer):
                    group = serializers.HyperlinkedIdentityField(view_name='gp',lookup_field='group_id',lookup_url_kwarg='xxx')
                    class Meta:
                        model = models.UserInfo
                        # fields = "__all__"
                        fields = ['id','username','password','group','roles']
                        depth = 0 # 0 ~ 10
    
                class UserInfoView(APIView):
                    def get(self,request,*args,**kwargs):
    
                        users = models.UserInfo.objects.all()
    
                        ser = UserInfoSerializer(instance=users,many=True,context={'request': request})
                        ret = json.dumps(ser.data, ensure_ascii=False)
                        return HttpResponse(ret)
    
        源码:
            对象, Serializer类处理;
            QuerySet,ListSerializer类处理;
            # ser.data
                    
    请求数据校验:
                        
            class XXValidator(object):
                def __init__(self, base):
                    self.base = base
    
                def __call__(self, value):
                    if not value.startswith(self.base):
                        message = '标题必须以 %s 为开头。' % self.base
                        raise serializers.ValidationError(message)
    
                def set_context(self, serializer_field):
                    """
                    This hook is called by the serializer instance,
                    prior to the validation call being made.
                    """
                    # 执行验证之前调用,serializer_fields是当前字段对象
                    pass
    
            class UserGroupSerializer(serializers.Serializer):
                title = serializers.CharField(error_messages={'required':'标题不能为空'},validators=[XXValidator('老男人'),])
    
    
            class UserGroupView(APIView):
    
                def post(self,request,*args,**kwargs):
    
                    ser = UserGroupSerializer(data=request.data)
                    if ser.is_valid():
                        print(ser.validated_data['title'])
                    else:
                        print(ser.errors)
    
                    return HttpResponse('提交数据')
                
    class XXValidator(object):
        def __init__(self, base):
            self.base = base
    
        def __call__(self, value):
            if not value.startswith(self.base):
                message = '标题必须以 %s 为开头。' % self.base
                raise serializers.ValidationError(message)
    
        def set_context(self, serializer_field):
            """
            This hook is called by the serializer instance,
            prior to the validation call being made.
            """
            # 执行验证之前调用,serializer_fields是当前字段对象
            pass
    
    class UserGroupSerializer(serializers.Serializer):
        title = serializers.CharField(error_messages={'required':'标题不能为空'},validators=[XXValidator('老男人'),])
    
    
    class UserGroupView(APIView):
    
        def post(self,request,*args,**kwargs):
    
            ser = UserGroupSerializer(data=request.data)
            if ser.is_valid():
                print(ser.validated_data['title'])
            else:
                print(ser.errors)
    
            return HttpResponse('提交数据')
    
    
        #未完成: 自定义验证规则时,需要钩子函数?请问钩子函数如何写?
        
             
    
        
  • 相关阅读:
    【Appium】appium踩坑记录:解决每次安装appium setting和Unlock
    Pycharm from XXX import XXX 引入本地文件标红报错(source_path&Python package)
    🍖02 不同平台更换pip源
    🍖pycharm 更换 pip 下载源
    🍖01 路飞学城项目分析
    🍖Vue-cli 创建项目
    🍖Vue 与后端交互
    🍖Vue 计算属性
    🍖Vue 虚拟DOM与Diff算法简介
    🍖Vue 生命期钩子
  • 原文地址:https://www.cnblogs.com/Skyda/p/10267611.html
Copyright © 2020-2023  润新知