Django REST Framework批量操作实例分析


本篇内容主要讲解“Django REST Framework批量操作实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Django REST Framework批量操作实例分析”吧!我们以下面的代码作为例子:models:serializers:views:myapp/urls:根urls:这是一个相当简单而又经典的场景。其中的Classroom模型不是重点,只是为了丰富元素,展示一般场景。创建数据:通过post方法访问127.0.0.1:8000/classrooms/创建一些教室数据。通过post方法访问127.0.0.1:8000/students/创建一些学生数据。

可以很清楚地看到DRF默认:通过GET /students/查看所有的学生通过GET /students/1/查看id为1的学生通过POST /students/携带一个数据字典,创建单个学生通过PUT/students/1/整体更新id为1的学生信息通过PATCH /students/1/局部更新id为1的学生信息通过DELETE/students/1/删除id为1的学生没有批量更新和删除的接口。并且当我们尝试向/students/,POST一个携带了多个数据字典的列表对象时,比如下面的数据:反馈给我们的如下图所示:错误提示:非法的数据,期望一个字典,但你提供了一个列表。至于尝试向更新和删除接口提供多个对象的id,同样无法操作。可见在DRF中,默认情况下,只能批量查看,不能批量创建、修改和删除。现实中,难免有批量的创建、修改和删除需求。那怎么办呢?只能自己写代码实现了。下面是初学者随便写的代码,未考虑数据合法性、安全性、可扩展性等等,仅仅是最基础的实现了功能而已:DRF本身提供了一个ListSerializer,这个类是实现批量创建的核心关键。当我们在实例化一个序列化器的时候,有一个关键字参数many,如果将它设置为True,就表示我们要进行批量操作,DRF在后台会自动使用ListSerializer来替代默认的Serializer。所以,实现批量创建的核心就是如何将many参数添加进去。这里,我们重写了get_serializer方法,通过if isinstance(self.request.data, list):语句,分析前端发送过来的数据到底是个字典还是个列表。如果是个字典,表示这是创建单个对象,如果是个列表,表示是创建批量对象。让我们测试一下。首先,依然可以正常地创建单个对象。然后如下面的方式,通过POST 往/students/发送一个列表:这里有个坑,可能会碰到AttributeError: ‘ListSerializer’ object has no attribute ‘fields’错误。这是响应数据格式的问题。没关系。刷新页面即可。也可以在POSTMAN中进行测试,就不会出现这个问题。先上代码:要注意,原DRF是通过DELETE/students/1/删除id为1的学生。那么如果我想批量删除id为1,3,5的三个数据怎么办?反正肯定是不能往/students/1/这样的url发送请求的。那么是构造一条这样的url吗?/students/1,3,5/?或者/students/?pk=1,3,5还是往/students/发送json数据[1,3,5]?这里,我采用/students/multiple_delete/?pks=1,3,5的形式。这样,它创建了一条新的接口,既避开了/students/这个接口,也能通过url发送参数。由于我们的视图继承的是ModelViewSet,所以需要通过action装饰器,增加一个同名的multiple_delete()方法。为了防止id和Python内置的id函数冲突。我们这里使用pks作为url的参数名。通过一个for循环,分割逗号获取批量主键值。通过主键值去数据库中查找对象,然后删除。(这里只是实现功能,未处理异常)下面,最好在POSTMAN中测试一下:注意请求是DELETE /students/multiple_delete/?pks=4,5再访问/students/,可以看到相关数据确实被删除了。代码如下:更新和删除不同的地方在于,它在提供主键值的同时,还需要提供新的字段值。所以,这里我们将主键值放在json数据中,而不是作为url的参数。请仔细阅读上面的代码注释。这里有个小技巧,其实可以根据HTTP的PUT和PATCH的不同,灵活设定partial参数的值。另外,要注意的对get_serializer()方法的处理。下面测试一下。在POSTMAN中通过PUT方法,访问/students/multiple_update/,并携带如下的json数据:上面是整体更新,局部更新也是可以的。前面,我们通过蹩脚的代码,实现了最基础的批量增删改查。但问题太多,不够优雅清晰、异常未处理、边界未考虑等等,实在是太烂。事实上,有这么个djangorestframework-bulk库,已经高水平地实现了我们的需求。这个库非常简单,核心的其实只有3个模块,核心代码也就300行左右,非常短小精干,建议精读它的源码,肯定会有收获。官网:https://pypi.org/project/djangorestframework-bulk/github:https://github.com/miki725/django-rest-framework-bulk最后更新:2015年4月最后版本:0.2.1它有两个免费云主机域名序列化器的版本:drf2drf3。我们用drf3。Python > = 2.7的Django > = 1.3Django REST framework > = 3.0.0使用pip:视图我们注释掉前面章节中的代码,编写下面的代码,使用bulk库来实现批量操作。bulk中的views(和mixins)非常类似drf原生的generic views(和mixins)然后我们将自动获得下面的功能:当然,原生的单个对象的操作也是依然支持的!要特别注意DELETE操作,这个例子里会直接将所有的数据全部删除。如果你想删除指定的一批数据,可以搭配filter_backends来过滤查询集,使用allow_bulk_destroy方法来自定义删除策略。可以看到bulk库对于RESTful的url没有任何改动,非常优雅,比我们上面的蹩脚方法强太多。路由也需要修改一下。bulk的路由可以自动映射批量操作,它对DRF原生的DefaultRouter进行了简单的封装:现在可以测试一下。下面提供一部分测试数据:建议在POSTMAN中进行测试PUT和PATCH要携带id值PUT要携带所有字段的值PATCH可以只携带要更新的字段的值DELETE一定要小心可以看到功能完全实现,批量操作成功。DRF3的API相比DRF2具有很多变化,尤其是在序列化器上。要在DRF3上使用bulk,需要注意以下几点:如果你的视图需要批量更新功能,则必须指定 list_serializer_class (也就是继承了 BulkUpdateModelMixin时)DRF3 从 serializer.validated_data中移除了只读字段。所以,无法关联 validated_dataListSerializer ,因为缺少模型主键这个只读字段。为了解决这个问题,你必须在你的序列化类中使用 BulkSerializerMixin ,这个混入类会添加模型主键字段到 validated_data中。默认情况,模型主键是 id ,你可以通过 update_lookup_field 属性来指定主键名:大多数API的每种资源都有两个级别的url:url(r'foo/', ...)url(r'foo/(?Pd+)/', ...)但是,第二个URL不适用于批量操作,因为该URL直接映射到单个资源。因此,所有批量通用视图仅适用于第一个URL。如果只需要某个单独的批量操作功能,bulk提供了多个通用视图类。例如,ListBulkCreateAPIView 将仅执行批量创建操作。有关可用的通用视图类的完整列表,请访问generics.py的源代码。大多数批量操作都是安全的,因为数据都是和每个对象关联的。例如,如果您需要更新3个特定资源,则必须在PUTPATCH的请求数据中明确的标识出那些资源的id。唯一的例外是批量删除,例如对第一种URL的DELETE请求可能会删除所有资源,而无需任何特殊确认。为了解决这个问题,批量删除混入类中提供了一个钩子,以确定是否应允许执行该批量删除请求,也就是allow_bulk_destroy方法:默认情况下,allow_bulk_destroy方法会检查查询集是否已过滤,如果没有过滤,则不允许执行该批量删除操作。此处的逻辑是,你知道自己在删除哪些对象,知道自己没有进行全部对象的删除操作。通俗地说就是,程序员对你的代码在作什么,心里要有数。下图是目录组织结构。分drf2和drf3,基本使用drf3。test目录我们不关心。核心其实就是根目录下的5个模块和drf3目录。其中的models.py文件是空的,没有代码。__init__.py这个模块就是简单地导入其它模块:#NOQA 注释的作用是告诉PEP8规范检测工具,这个地方不需要检测。也可以在一个文件的第一行增加 #flake8:NOQA 来告诉规范检测工具,这个文件不用检查。serializers.py源代码:就是针对不同的DRF版本,导入不同的serializers。mixins.py源代码:和serializers.py类似,针对不同的DRF版本,导入不同的mixins。routes.py搭配bulk的BulkModelViewSet视图类进行工作。源代码:对DRF原生的DefaultRouter路由模块进行再次封装,主要是修改三个HTTP方法的映射关系,将它们映射到bulk库的mixins方法。generics.py这个模块的风格和DRF的源码非常类似,都是各种继承搭配出来各种类视图。里面混用了DRF原生的mixin和bulk自己写的mixin。主要是将http的method映射到视图类中对应的处理方法。源代码:drf3/mixins.py这个模块实现了核心的业务逻辑。请注意阅读源代码中的注释。源代码:drf3/serializers.py这个模块只有两个类,它们提供了2个功能。BulkSerializerMixin:往验证后的数据中添加主键字段的值BulkListSerializer:提供批量更新的update方法源代码:到此,相信大家对“Django REST Framework批量操作实例分析”有了更深的了解,不妨来实际操作一番吧!这里是百云主机网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

相关推荐: 怎么用Python画国家的国旗

这篇文章主要为大家展示免费云主机域名了“怎么用Python画国家的国旗”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“怎么用Python画国家的国旗”这篇文章吧。五星红旗是中华人民共和国的国旗,它是由四颗小的黄五角星…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

Like (0)
Donate 微信扫一扫 微信扫一扫
Previous 09/10 15:49
Next 09/10 15:49

相关推荐