1227 十大接口使用,Response封装深度查询

目录

  • 十大接口
    • 1.序列化了解配置
    • 2.Response的二次封装
    • 3.深度查询
      • 3.1 子序列化:
      • 3.2 配置depth
      • 3.3 插拔式@property
    • 4. 十大接口实现
      • 4.1 单查群查(get)
      • 4.2 单删群删(delete)
      • 4.3 单增群增(post)
      • 4.4 整体单改群改(put)
      • 4.5 局部单改群改(patch)
    • 新中国前夕

十大接口

1.序列化了解配置

  • fields = __all__ 将所对应类中的所有名成空间
  • exclude = [' ',], 排除某一字段,其他的需要
  • depth = 1 查询的深度设置(遇到外键就找深度查询)

外键字段默认显示的是外键值(int类型,不会自己进行深度查询)

2.Response的二次封装

自定义Response的封装,将数据返回自定义使用

from .response import APIResponse
class BookAPIView(APIView):
    def get(self,request,*args,**kwargs):
        book_query = models.Book.objects.all()
        # 序列化模块
        book_ser = serializers.BookModelSerializer(book_query,many=True)
    #     原先的返回数据
    #     return Response(
    #         data = {
    #         'status':0,
    #         'msg':'ok',
    #         'results':book_ser.data
    #     })
    #     自定义response返回数据
        return APIResponse(results=book_ser.data)

response的二次封装

# response的二次封装
from rest_framework.response import Response
class APIResponse(Response):
    def __init__(self, status=0,msg='ok',results=None,http_status=None, headers=None,
                 exception=False, content_type=None,**kwargs):
        # 将status,msg,results格式化成data
        data = {
            'status':status,
            'msg' : msg,
        }
        # results只要不为空都是数据:False,0,'',都是数据,条件不能写if results
        if results is not None:
            data['results'] = results
        # 将kwargs中额外的kv数据添加到data中
        data.update(**kwargs)
        super().__init__(data=data,status=http_status,headers=headers,exception=exception,content_type=content_type)

3.深度查询

外键字段显示的是外键值(int类型),不会自己进行深度查询

# 深度查询方式
# 1.子序列化,必须有子序列化类配合,不能反序列化了
# 2.配置depth: 自动深度查询的是关联表的所有字段,数据量太多
# 3.插拔式@property:名字不能与外键名同名

3.1 子序列化:

必须有子序列化类配合,不能反序列化了

    class Meta:
        model = models.Book
        fields = ['name','price','publish','authors']

3.2 配置depth

自动深度查询的是关联表的所有字段,数据量太多
depth = 1

3.3 插拔式@property

名字与不能与外键同名

直接在model表类中设定@property方法,跨表查询并返回
然后在fields中插入使用
# 多个数据
    @property
    def author_list(self):
        # 存放所有作者格式化成数据的列表
        author_list_temp = []
        # 获取所有作者对象
        authors = self.author.all()
        # 遍历所有作者对象,获取数据
        for author in authors:
            author_dic = {
                'name':author.name
            }
            # 判断个人的详情页有无(手机号有无),有详情才处理信息
            try:
                author_dic['mobile'] = author.detail.mobile
            except:
                author_dic['mobile'] = '无'
            # 将手机信息添加至数据列表中
            author_list_temp.append(author_dic)
        return author_list_temp

4. 十大接口实现

4.1 单查群查(get)

from .response import APIResponse
class BookAPIView(APIView):
    # 单查群查
    def get(self,request,*args,**kwargs):
        pk = kwargs.get('pk')
        if pk:
            book_obj = models.Book.objects.filter(is_delete=False,pk=pk).first()
            # 序列化模块
            book_ser = serializers.BookModelSerializer(book_obj)
        else:
            book_query = models.Book.objects.filter(is_delete=False).all()
            book_ser = serializers.BookModelSerializer(book_query,many=True)
        return APIResponse(results=book_ser.data)

4.2 单删群删(delete)

单删: 接口: /books/(pk)/  数据:空
群删: 接口: /book/        数据:[pk1,...pkn]
逻辑: 修改is_delete字段,修改成功代表删除成功,修改失败代表删除失败
传入1,2,a  数据有误,不会删除
1,100   只会删除1,删除成功
    # 单删群删
    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        if pk:
            # 将单删格式化成群删一条
            pks = [pk]
        else:
            # 群删数据,需要校验数据是否正确
            pks = request.data
        try:
            # 如果数据有误,数据库会执行出错
            # update 是修改,获取的rows则是受影响的行
            rows = models.Book.objects.filter(is_delete=False, pk__in=pks).update(is_delete=True)
        except:
            return APIResponse(1,'数据有误')

        if rows:
            return APIResponse(0,'删除成功')
        return APIResponse(1,'删除失败')

----------------------------------------------------------

        # # update 是修改,获取的rows则是受影响的行
        # rows = models.Book.objects.filter(is_delete=False,pk=pk).update(is_delete=True)
        # # 群删
        # pks = request.data
        # # pk__in 在 pks中的所有pk
        # rows = models.Book.objects.filter(is_delete=False,pk__in=pks).update(is_delete=True)
        # if rows:
        #     return APIResponse(0,'删除成功')
        # # 失败
        # return APIResponse(1,'删除失败')

4.3 单增群增(post)

单增: 接口: /books/       数据:{}
群增: 接口: /book/        数据:[{},...,{}]
逻辑: 将数据给序列化类处理,数据的类型关系到many属性是否为true
    def post(self, request, *args, **kwargs):
        # 这里判断数据类型,来确定mang的属性(单改字典,群改列表套字典)
        if isinstance(request.data,dict):
            many=False
        elif isinstance(request.data,list):
            many = True
        else:
            return Response(data={'Detail':'数据有误'},status=400)
        # 序列化数据改操作
        book_ser = serializers.BookModelSerializer(data=request.data,many=many)
        book_ser.is_valid(raise_exception=True)
        book_obj_or_list = book_ser.save()
        return APIResponse(results=serializers.BookModelSerializer(book_obj_or_list,many=many).data)

listserializers类分析

modelserializers完成的是单增
listserializers完成的群增,借助modelserializers遍历完成群增

两者类之间如何完成绑定

多表操作class Meta中设置:
    class Meta:
        # modelserializer默认配置了listSerializer辅助类,帮助完成群增群改
        # list_serializer_class = serializers.ListSerializer
        # 如果只有群增,是不需要自定义配置的,但要完成群改,必须自定义配置
        list_serializer_class = BookListserializer

        
class BookListserializer(serializers.ListSerializer):
    # 自定义的群增群改辅助类,没有必要重写create方法
    def create(self, validated_data):
        return super().create(validated_data)
    # 自定义update方法
    def update():
        pass

4.4 整体单改群改(put)

modelSerializer类中
    instance 接收的是对象(查询出来的数据对象)
    data 接收的是前端传过来的数据的
    
    所以反序列化需要指定 data=request.data
    然后进行保存数据库的操作

单改

# 整体单改群改
    def put(self,request,*args,**kwargs):
        pk = kwargs.get('pk')
        # 单改
        if pk:
            # 与增的区别在于,需要明确被修改的对象,交给序列化类
            #     在源码中会判断数据的instance,如果有值走update改操作,没值走create操作
            try:
                # 获取修改的数据对象(pk可能出错)
                book_instance = models.Book.objects.get(is_delete=False,pk=pk)
            except:
                return Response({'Detail':'pk error'},status=400)

            # 将数据对象,与前端数据传递给BookModelSerializer进行改操作
            book_ser = serializers.BookModelSerializer(instance=book_instance, data=request.data)
            # 校验数据
            book_ser.is_valid(raise_exception=True)
            book_obj = book_ser.save()
            return APIResponse(results=serializers.BookModelSerializer(book_obj).data)

群改

分析

  • 数据是列表套字典,每个字段必须带pk,就是指定要修改的对象,如果有一条数据没有带pk,就报错
  • 如果pk对应的数据已经被删除,或是对应的对象不存在,可以认为整个数据有误(建议),可以认为将这些错误数据刨除即可
        # 群改
        else:
            # 获取所有的数据
            request_data = request.data
            try:
                pks = []
                # 获取所有修改数据的pk(并剔除)
                for dic in request_data:
                    # pop会根据有无pk数据自动抛异常
                    pk = dic.pop('pk')
                    pks.append(pk)
                # 查询获取所有的数据对象(pks中)
                book_query = models.Book.objects.filter(is_delete=False,pk__in=pks).all()
                # 判断pks查询出的数据pk值存在与否
                if len(pks) != len(book_query):
                    # 报错被捕获
                    raise Exception('pk 对应的数据不存在')
            except Exception as e:
                return Response({'detail':'%s' % e},status=400)

            # 序列化前台提供数据,many=true,instance得到的是列表数据
            book_ser = serializers.BookModelSerializer(instance=book_query,data=request.data,many=True)
            book_ser.is_valid(raise_exception=True)
            book_list = book_ser.save()
            # save中如果instance有值则走update方法,所以需要自定义
            return APIResponse(results=serializers.BookModelSerializer(book_list,many=True).data)

自定义update方法

    # 自定义update方法
    def update(self, instance_list, validated_data_list):
        return [
            # 遍历数据的索引与attrs获取对象的数据,一一对应使用update方法
            self.child.update(instance_list[index],attrs) for index,attrs in enumerate(validated_data_list)
        ]

4.5 局部单改群改(patch)

局部修改字段(partial=True)

设置partial=True的序列化类,参与反序列化的字段,都会置为选填字段

1. 提供了值的字段发生修改
2. 没有提供的字段则不修改,采用原来对象的值

将序列化类时数据添加`partial=True`将所有数据变为可选,其他与put一样

序列化传参(context=)

设置context的值
    目的:在序列化完成自定义校验(局部与全局钩子时,可能需要视图类中的变量,如请求对象request)
    
    可以通过context将其传入,在序列化校验方法中,self.context就能拿到传入的视图类中的变量

代码

    # 局部单改群改
    def patch(self,request,*args,**kwargs):
        pk = kwargs.get('pk')
        # 单改
        if pk:
            try:
                book_instance = models.Book.objects.get(is_delete=False,pk=pk)
            except:
                return Response({'Detail':'pk error'},status=400)

            # 设置partial=True的序列化类,参与反序列化的字段,都会置为选填字段
            # 1. 提供了值的字段发生修改
            # 2. 没有提供的字段则不修改,采用原来对象的值

            # 设置context的值,目的:在序列化完成自定义校验(局部与全局钩子时,可能需要视图类中的变量,如请求对象request)
            # 可以通过context将其传入,在序列化校验方法中,self.context就能拿到传入的视图类中的变量
            book_ser = serializers.BookModelSerializer(instance=book_instance, data=request.data,partial=True,context={'request':request})
            # 校验数据
            book_ser.is_valid(raise_exception=True)
            book_obj = book_ser.save()
            return APIResponse(results=serializers.BookModelSerializer(book_obj).data)
        # 群改
        else:
            # 获取所有的数据
            request_data = request.data
            try:
                pks = []
                # 获取所有修改数据的pk(并剔除)
                for dic in request_data:
                    pk = dic.pop('pk')
                    pks.append(pk)
                book_query = models.Book.objects.filter(is_delete=False,pk__in=pks).all()
                # 判断pks查询出的数据pk值存在与否
                if len(pks) != len(book_query):
                    # 报错被捕获
                    raise Exception('pk 对应的数据不存在')
            except Exception as e:
                return Response({'detail':'%s' % e},status=400)

            book_ser = serializers.BookModelSerializer(instance=book_query,data=request.data,many=True,partial=True)
            book_ser.is_valid(raise_exception=True)
            book_list = book_ser.save()
            return APIResponse(results=serializers.BookModelSerializer(book_list,many=True).data)

新中国前夕

1894  甲午战争
民间运动
1900 义和团运动
慈禧支持义和团,并开战
八国联军  最早三万人 5万人
    意大利80人
    清军看不起义和团,卖了他们
辛丑条约
甲午海战之后,清政府新建北洋新军
1911年辛亥革命推翻帝制,武昌起义
第一次世界大战 1914.6
袁世凯则窃取革命果实,大总统
复辟帝制,
孙中山蔡锷革命
袁世凯6月身死
北洋军阀割据
国共合作成立国民政府,蒋领导开始北伐战争  1926
1927 四一二反革命政变
    城市革命 - 农村包围城市
国民革命军占领北京,1928,北洋结束
土地革命(第一次国共战争) 1927-1936
    没收地主获取农民支持
    围剿与反围剿
    长征
1931九一八事变
    一二八事变
    满洲国
    长城战役
西安事变 1936 (沟通放弃围剿)
卢沟桥事变 1937,7,7 
    (第二次国共合作) 
第二次世界大战  1939-1945
抗日战争
    国共摩擦
原子弹1945
日本投降  1945 
解放战争(第二次国共内战)  1945-1949
    土地改革(贫下中农,大地主)
    三大战役
1949 新中国成立

你可能感兴趣的:(1227 十大接口使用,Response封装深度查询)