django_rest framework 接口开发(一)
阅读原文时间:2023年07月12日阅读:1

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

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