第二个serializer校验失败时如何回滚已提交的data entry数据
解决方法
核心使用Django自带的数据库事务机制即可实现要求,无需调整原有校验逻辑的顺序。
- 首先导入事务模块
from django.db import transaction
- 将你的全量业务逻辑包裹在
transaction.atomic()上下文管理器中,修改后代码如下:
from django.db import transaction # 所有关联的数据库操作放入同一个事务块 with transaction.atomic(): data = { "order_type":"order", "user_id":user_id, "order_total":order_total, ... } serialzier = UserOrderSer(data=data) # 校验失败自动抛出异常,触发事务回滚 if serialzier.is_valid(raise_exception=True): serialzier.save() product_data = [] for i in all_response: product_data.append({ "order_id": serialzier.data['order_id'], "product_id":i['product_id'], "product_name":i['product_name'], "product_price": i['selling_price'], ... }) product_serializer = UserOrderProductSer(data=product_data,many=True) # 此处校验失败抛出的异常同样会触发事务回滚,已经写入的订单数据会被撤销 if product_serializer.is_valid(raise_exception=True): product_serializer.save()
说明
transaction.atomic()会将包裹范围内的所有数据库操作绑定为原子操作,要么全部执行成功,要么全部失败回滚,完美匹配需求。- 序列化器的
is_valid(raise_exception=True)在校验失败时会自动抛出ValidationError,该异常会触发事务自动回滚,不需要额外编写回滚代码。 - 如果你需要自定义校验失败的返回逻辑,只需在
transaction.atomic()上下文外部捕获对应的异常即可,不要在事务块内部吞掉校验抛出的异常,否则会导致回滚不生效。
内容的提问来源于stack exchange,提问作者Ajay Chaurasia
相关产品推荐
相关产品推荐

