DRF--十大接口方法:单查群查,单删群删,单增群增,整体单改群改,局部单改群改

from rest_framework.views import APIView
from rest_framework.response import Response
from . import models, serializers
from .response import APIResponse

# 出版社群查
class PublishAPIView(APIView):
    def get(self, request, *args, **kwargs):
        publish_query = models.Publish.objects.all()
        publish_ser = serializers.PublishModelSerializer(publish_query, many=True)
        return APIResponse(results=publish_ser.data)

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)
        # return Response(data=book_ser.data)

    # 单删群删
    def delete(self, request, *args, **kwargs):
        """
        单删:接口:/books/(pk)/   数据:空
        群删:接口:/books/   数据:[pk1, ..., pkn]
        逻辑:修改is_delete字段,修改成功代表删除成功,修改失败代表删除失败
        """
        pk = kwargs.get('pk')
        if pk:
            pks = [pk]  # 将单删格式化成群删一条
        else:
            pks = request.data  # 群删
        try:  # 数据如果有误,数据库执行会出错
            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, '删除失败')

    # 单增群增
    def post(self, request, *args, **kwargs):
        """
        单增:接口:/books/   数据:{...}
        群增:接口:/books/   数据:[{...}, ..., {...}]
        逻辑:将数据给系列化类处理,数据的类型关系到 many 属性是否为True
        """
        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)

    # 整体单改群改
    def put(self, request, *args, **kwargs):
        """
        单改:接口:/books/(pk)/   数据:{...}
        群增:接口:/books/   数据:[{pk, ...}, ..., {pk, ...}]
        逻辑:将数据给系列化类处理,数据的类型关系到 many 属性是否为True
        """
        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)

            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)
        else:  # 群改
            # 分析(重点):
            # 1)数据是列表套字典,每个字典必须带pk,就是指定要修改的对象,如果有一条没带pk,整个数据有误
            # 2)如果pk对应的对象已被删除,或是对应的对象不存在,可以认为整个数据有误(建议),可以认为将这些错误数据抛出即可
            request_data = request.data
            try:
                pks = []
                for dic in request_data:
                    pk = dic.pop('pk')  # 解决分析1,没有pk pop方法就会抛异常
                    pks.append(pk)

                book_query = models.Book.objects.filter(is_delete=False, pk__in=pks).all()
                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)
            book_ser.is_valid(raise_exception=True)
            book_list = book_ser.save()
            return APIResponse(results=serializers.BookModelSerializer(book_list, many=True).data)

    # 局部单改群改
    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 = []
                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()
                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)

原文地址:https://www.cnblogs.com/ludundun/p/12109641.html

时间: 2024-08-05 09:27:33

DRF--十大接口方法:单查群查,单删群删,单增群增,整体单改群改,局部单改群改的相关文章

drf序列化高级、自定义只读只写、序列化覆盖字段、二次封装Response、数据库查询优化(断关联)、十大接口、视图家族、自动补全图片链接

目录 自定义只读 自定义只写 序列化覆盖字段 二次封装Response 数据库关系分析 断外键关联关系 ORM操作外键关系 ORM四种关联关系 基表 序列化类其他配置(了解) 十大接口 BaseSerializer初始化方法 十大接口序列化总结 单查群查 单增群增 单删群删 单整体改/群整体改 单局部改/群局部改 群增群改配置 十大接口小结 字段提供就校验,不提供拉到 DjangoORM内置优化机制:一次最多查21条数据 models.py response.py serializers.py

导包补充,深度查询(深度序列化),十大接口

目录 一.导包补充 二.深度查询 1. 子序列化和depth方法 (1)什么是子序列化 (2)__all__ 方法 exclude方法 (3)子序列化实例 2. 插拔式 三.十大接口 1. 十大接口中注意点(很重要) 2. 实例 一.导包补充 在导包时,如果用from 文件1 import *,则文件1中的以下划线开头的变量,都不能访问.无论是单下划线还是双下线. 用import 文件1的方式,还是能访问到文件1中以下划线开头的变量,没有影响. 当我们用from 文件1 import *的方式导

bookserlizer 十大接口

目录 一.导包补充 二.深度查询 子序列化和depth方法 (1)什么是子序列化 (2)all 方法 exclude方法 (3)子序列化实例 插拔式 三.十大接口 十大接口中注意点(很重要) 实例 一.导包补充 在导包时,如果用from 文件1 import ,则文件1中的以下划线开头的变量,都不能访问.无论是单下划线还是双下线. 用import 文件1的方式,还是能访问到文件1中以下划线开头的变量,没有影响. 当我们用from 文件1 import 的方式导包时,怎么才能访问到其中以下划线开头

序列化类外键字段的覆盖,十大接口序列化总结,视图家族

序列化类外键字段的覆盖 """ 1)在序列化类中自定义字段,名字与model类中属性名一致,就称之为覆盖操作 (覆盖的是属性的所有规则:extra_kwargs中指定的简易规则.model字段提供的默认规则.数据库唯一约束等哪些规则) 2)外键覆盖字段用PrimaryKeyRelatedField来实现,可以做到只读.只写.可读可写三种形式 只读:read_only=True 只写:queryset=关联表的queryset, write_only=True 可读可写:que

互联网十大数据分析方法-对比分析

什么是对比分析对比分析是数据分析中一种基础分析方法.对于互联网产品经常关注的转化率指标,如果转化率为5%,不能说明这个指标的好坏,如果该细分行业的行业平均转化率为10%,通过对比其实指标还是有很大优化空间的.用户行为分析和APP数据分析中都会大量的用到对比分析方法.对比分析是对一个孤立的指标找到一个参照系,否则一个鼓励的指标其实没有任何实际的意义.常见对比分析方法时间序列对比: 按照时间序列对数据进行对比分析,分析产品运营数据变化趋势,从而给产品运营提供决策.同比:同比一般情况下是今年第n月与去

CSIC_716_20200221【drf--自定义外键字段、十大接口】

自定义序列化外键字段: 在序列化组件中  serializers.PrimaryKeyRelatedField(read_only=True)  #只读覆盖 serializers.PrimaryKeyRelatedField(queryset=.....all()  )  # 可读可写 serializers.PrimaryKeyRelatedField(queryset=.....all() ,write_only=True  )  # 只写 原文地址:https://www.cnblogs

django-rest framework 接口规范 原生django接口、单查群查 postman工具 CBV源码解析

内容了解 """ 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件.解析组件.响应组件 4.序列化组件(灵魂) 5.三大认证(重中之重):认证.权限(权限六表).频率 6.其他组件:过滤.筛选.排序.分页.路由 """ # 难点:源码分析 一.接口 1.什么是 接口:联系两个物质的媒介,完成信息交互 web程序中:联系前台页面与后台数据库的媒介 web接口组成: url:

互联网运营中的10大数据分析方法

https://www.sohu.com/a/212888005_468714 http://www.woshipm.com/data-analysis/758063.html 道家强调四个字,叫“道.法.术.器”.“器”是指物品或工具,在数据分析领域指的就是数据分析的产品或工具,“工欲善其事,必先利其器”:“术”是指操作技术,是技能的高低.效率的高下,如对分析工具使用的技术(比如用Excel进行数据分析的水平):“法”是指选择的方法,有句话说“选择比努力重要”:“道”是指方向,是指导思想,是战

电商干货!1000万烧出来的高点击率钻展创意图十大原则(营销&人性)

梦想凯歌:创意图的钻展的灵魂,没有创意图你什么都不是.无论是日常推广还是做大促活动,创意图是测试的重中之重,一定要提前测试好每一个资源位的创意图.今天这篇好文是一个资深电商设计师在操作钻展烧了1000多万后总结的经验,不少技巧可以用在Banner设计上. 创意图是你获取流量的入口,由创意图延升到落地页,进而是整一个活动项目. 所以,这节课很关键,也是我这系列课程的重点.到目前操作钻展也至少烧了1000多万了. 很多朋友常常发图片给梦想凯歌,问如何优化?这十大原则是我梦想凯歌做创意图的总结! 虽然