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('提交数据')


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

    

猜你喜欢

转载自www.cnblogs.com/Skyda/p/10267611.html
今日推荐